আমি কিভাবে একটি নতুন লাইন প্রতিস্থাপন করতে পারি(\ n) sed ব্যবহার করে?
(20)
আমি কীভাবে নতুন কমান্ডটি প্রতিস্থাপন করতে পারি ( \n
) sed কমান্ড ব্যবহার করে?
আমি ব্যর্থ চেষ্টা করেছি:
sed 's#\n# #g' file
sed 's#^$# #g' file
আমি কিভাবে এটা ঠিক করব?
সহজ থেকে বুঝতে সমাধান
আমি এই সমস্যা ছিল। Kicker ছিল যে আমি BSD এর (ম্যাক ওএস এক্স) এবং GNU এর (লিনাক্স এবং Cygwin ) sed
এবং tr
তে কাজ করার সমাধান প্রয়োজন:
$ echo 'foo
bar
baz
foo2
bar2
baz2' \
| tr '\n' '\000' \
| sed 's:\x00\x00.*:\n:g' \
| tr '\000' '\n'
আউটপুট:
foo
bar
baz
(নতুন লাইন পিছনে আছে)
এটি লিনাক্স, ওএস এক্স, এবং বিএসডি -তে এমনকি UTF-8 সমর্থন ছাড়াই কাজ করে বা ক্র্যাফপি টার্মিনালের সাথে কাজ করে।
অন্য অক্ষর দিয়ে নতুন লাইন স্যুইচ করার জন্য
tr
ব্যবহার করুন।NULL
(\000
বা\x00
) চমৎকার কারণ\x00
UTF-8 সমর্থনের প্রয়োজন নেই এবং এটি ব্যবহার করা যাবে না।NULL
মিলিত করার জন্যsed
ব্যবহার করুনযদি আপনার প্রয়োজন হয় তবে অতিরিক্ত নতুন লাইনগুলি
tr
করতেtr
ব্যবহার করুন
কোন স্ট্রিং সঙ্গে নতুন লাইন প্রতিস্থাপন, এবং শেষ সর্বশেষ লাইন প্রতিস্থাপন
বিশুদ্ধ tr
সমাধান শুধুমাত্র একটি অক্ষর দিয়ে প্রতিস্থাপন করতে পারে, এবং বিশুদ্ধ sed
সমাধানগুলি ইনপুটটির সর্বশেষ নতুন লাইনটিকে প্রতিস্থাপন করে না। নিচের সমাধানগুলি এই সমস্যার সমাধান করে এবং বাইনারি ডেটা (এমনকি একটি UTF-8 লোকেল সহও) নিরাপদ বলে মনে হয়:
printf '1\n2\n3\n' |
sed 's/%/%p/g;s/@/%a/g' | tr '\n' @ | sed 's/@/<br>/g;s/%a/@/g;s/%p/%/g'
ফলাফল:
1<br>2<br>3<br>
Awk ব্যবহার করে:
awk "BEGIN { o=\"\" } { o=o \" \" \$0 } END { print o; }"
gnu sed একটি বিকল্প -z
নল পৃথক রেকর্ড (লাইন) জন্য আছে। আপনি শুধু কল করতে পারেন:
sed -z 's/\n/ /g'
আপনি xargs
ব্যবহার করতে পারেন - এটি ডিফল্টভাবে একটি স্থান দিয়ে \n
প্রতিস্থাপন করবে।
যাইহোক, আপনার ইনপুটটি যদি বিচ্ছিন্ন unterminated quote
কোনও ক্ষেত্রে থাকে তবে এটি সমস্যা হবে, উদাহরণস্বরূপ যদি প্রদত্ত লাইনের উদ্ধৃতি লক্ষণ মেলে না।
আমি একজন বিশেষজ্ঞ নই, তবে আমি মনে করি আপনি প্রথমে প্যাটার্ন স্পেসে পরবর্তী লাইন যুক্ত করতে হবে, বিজ " N
" ব্যবহার করে। সেড অ্যান্ড অ্যাজক (ডেল ডঘের্টি এবং আর্নল্ড রবিনস; ওরেলি 1997 , পূর্বরূপে পৃষ্ঠা 107) বইটির "অ্যাডভান্সড সিড কমান্ড" বিভাগে "মাল্টিলাইন প্যাটার্ন স্পেস" থেকে:
মাল্টিলাইন পরবর্তী (এন) কমান্ড ইনপুট একটি নতুন লাইন পড়া এবং প্যাটার্ন স্পেস বিষয়বস্তুর মধ্যে যোগ করে একটি multiline প্যাটার্ন স্থান তৈরি করে। প্যাটার্ন স্পেস এবং নতুন ইনপুট লাইনের আসল সামগ্রীগুলি একটি নতুন লাইন দ্বারা পৃথক করা হয়। এমবেডেড নতুন লাইনের অক্ষরটি পাল্টা ক্রম অনুসারে "\ n" প্যাটার্নগুলির সাথে মিলে যেতে পারে। একটি মাল্টিলাইন প্যাটার্ন স্পেসে, মেটাচারার "^" প্যাটার্ন স্পেসের প্রথম চরিত্রের সাথে মেলে এবং চরিত্রগুলি কোনও এমবেডেড নতুন লাইন অনুসরণ করে না। একইভাবে, "$" শুধুমাত্র প্যাটার্ন স্পেসে চূড়ান্ত নতুন লাইনের সাথে মেলে, এবং কোনও এমবেডেড নয়লাইন (গুলি) নয়। পরবর্তী কমান্ডটি কার্যকর হওয়ার পরে, স্ক্রিপ্টের পরে পরবর্তী কমান্ডগুলিতে নিয়ন্ত্রণ করা হয়।
man sed
থেকে:
[2addr] এন
আসল উপাদান থেকে সংযুক্ত উপাদান আলাদা করার জন্য একটি এমবেডেড নতুন লাইন চরিত্র ব্যবহার করে প্যাটার্ন স্পেসে ইনপুটটির পরবর্তী লাইন যুক্ত করুন। উল্লেখ্য যে বর্তমান লাইন নম্বর পরিবর্তন।
আমি এটি ব্যবহার করেছি (একাধিক) খারাপভাবে বিন্যাসযুক্ত লগ ফাইল, যা অনুসন্ধান স্ট্রিং একটি "অনাথ" পরবর্তী লাইনে পাওয়া যেতে পারে।
উপরের "ট্র" সমাধানটির প্রতিক্রিয়ায়, উইন্ডোজ (সম্ভবত ট্রু এর Gnuwin32 সংস্করণ ব্যবহার করে) প্রস্তাবিত সমাধান:
tr '\n' ' ' < input
আমার জন্য কাজ করছিল না, এটি কোনও কারণে ত্রুটি বা আসলে \ nw / '' প্রতিস্থাপন করবে।
Tr এর অন্য বৈশিষ্ট্য ব্যবহার করে, "মুছে ফেলুন" বিকল্পটি -ড কাজ করেছে যদিও:
tr -d '\n' < input
বা '\ r \ n' এর পরিবর্তে '\ n'
একটি সংক্ষিপ্ত অদ্ভুত বিকল্প:
awk 1 ORS=' '
ব্যাখ্যা
একটি awk প্রোগ্রাম শর্তাবলী নির্মিত হয় যা শর্তাধীন কোড-ব্লক গঠিত, অর্থাত্:
condition { code-block }
কোড-ব্লক বাদ দেওয়া হলে, ডিফল্ট ব্যবহার করা হয়: { print $0 }
। সুতরাং, 1
সত্য শর্ত হিসাবে ব্যাখ্যা করা হয় এবং প্রতিটি লাইনের জন্য print $0
করা হয়।
যখন awk
ইনপুটটি পড়ে তখন এটি RS
(রেকর্ড বিভাজক) এর মানের ভিত্তিতে রেকর্ডে বিভক্ত হয়, যা ডিফল্টভাবে একটি নতুন লাইন হয়, সুতরাং ডিফল্টভাবে ডিফল্টভাবে ইনপুট লাইন অনুসারে পজিশন করে। বিভাজন এছাড়াও ইনপুট রেকর্ড থেকে RS
stripping জড়িত থাকে।
এখন, যখন একটি রেকর্ড মুদ্রণ করা হয়, ORS
(আউটপুট রেকর্ড বিভাজক) এটি যুক্ত করা হয়, ডিফল্ট আবার একটি নতুন লাইন। সুতরাং একটি স্থান থেকে ORS
পরিবর্তন করে সব নতুন লাইন স্পেস পরিবর্তন করা হয়।
এটি সাধারণ যে "স্বাভাবিক" প্রতিস্থাপনের পরে নতুন লাইন প্রবর্তন করে। প্রথম, এটি নতুন লাইন গৃহস্থালি trims, তারপর এটি আপনার নির্দেশাবলী অনুযায়ী প্রসেস, তারপর এটি একটি নতুন লাইন প্রবর্তন।
সিডি ব্যবহার করে আপনি প্রতিটি ইনপুট লাইনের জন্য আপনার পছন্দের স্ট্রিং সহ একটি লাইন (নতুন লাইন গৃহস্থালি নয়) এর "শেষ" প্রতিস্থাপন করতে পারেন; কিন্তু, sed বিভিন্ন লাইন আউটপুট হবে। উদাহরণস্বরূপ, ধরুন আপনি "===" দিয়ে "লাইনের শেষ" প্রতিস্থাপন করতে চান (একটি স্থান সহ প্রতিস্থাপন করার চেয়ে আরো সাধারণ):
PROMPT~$ cat <<EOF |sed 's/$/===/g'
first line
second line
3rd line
EOF
first line===
second line===
3rd line===
PROMPT~$
নতুন লাইন গৃহস্থালিটি স্ট্রিং দিয়ে প্রতিস্থাপন করার জন্য, আপনি অদক্ষভাবে, যদিও, "নির্দিষ্ট গৃহস্থালি" দিয়ে নতুন লাইনের প্রতিস্থাপন করার আগে, পূর্বে নির্দেশিত tr হিসাবে ব্যবহার করতে পারেন এবং তারপরে যে বিশেষ স্ট্রিংটি আপনি চান তা দিয়ে প্রতিস্থাপন করতে sed ব্যবহার করুন। ।
উদাহরণ স্বরূপ:
PROMPT~$ cat <<EOF | tr '\n' $'\x01'|sed -e 's/\x01/===/g'
first line
second line
3rd line
EOF
first line===second line===3rd line===PROMPT~$
এর উত্তরঃ একটি লেবেল ...
আমি কিভাবে একটি নতুন লাইন প্রতিস্থাপন করতে পারি (\ n) sed ব্যবহার করে?
... কমান্ড লাইনে ফ্রিবসড 7.2 এ কাজ করে না:
( echo foo ; echo bar ) | sed ':a;N;$!ba;s/\n/ /g' sed: 1: ":a;N;$!ba;s/\n/ /g": unused label 'a;N;$!ba;s/\n/ /g' foo bar
কিন্তু যদি আপনি একটি স্ক্রিপ্টে sed স্ক্রিপ্টটি ব্যবহার করেন বা ব্যবহার করেন -ইড স্ক্রিপ্টটি "বিল্ড" করতে ...
> (echo foo; echo bar) | sed -e :a -e N -e '$!ba' -e 's/\n/ /g' foo bar
অথবা ...
> cat > x.sed << eof
:a
N
$!ba
s/\n/ /g
eof
> (echo foo; echo bar) | sed -f x.sed
foo bar
হয়তো ওএস এক্স মধ্যে sed অনুরূপ।
কে কে দরকার? এখানে bash
উপায়:
cat test.txt | while read line; do echo -n "$line "; done
জিএনইউ সঙ্গে এই সমাধান ব্যবহার করুন sed
:
sed ':a;N;$!ba;s/\n/ /g' file
এটি একটি লুপে পুরো ফাইলটি পড়বে, তারপরে একটি স্থান সহ নতুন লাইন প্রতিস্থাপন করবে।
ব্যাখ্যা:
- মাধ্যমে একটি লেবেল তৈরি করুন
:a
। -
N
মাধ্যমে প্যাটার্ন স্থান বর্তমান এবং পরবর্তী লাইন যোগ করুন। - যদি আমরা শেষ লাইনের আগে, তৈরি লেবেলটির শাখা
$!ba
($!
মানে শেষ লাইনে এটি করা হবে না কারণ এটি একটি চূড়ান্ত নতুন লাইন হওয়া উচিত)। - অবশেষে প্রতিস্থাপন প্রতি নতুন রেখাটিকে প্যাটার্ন স্পেসে (যা পুরো ফাইলটি) একটি স্থান দিয়ে প্রতিস্থাপন করে।
এখানে ক্রস-প্ল্যাটফর্ম সামঞ্জস্যপূর্ণ সিনট্যাক্স রয়েছে যা বিএসডি এবং ওএস এক্স এর সিডি ( @ বেঞ্জি মন্তব্য অনুসারে ) দিয়ে কাজ করে:
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file
আপনি দেখতে পারেন, এই অন্যথায় সহজ সমস্যা জন্য sed
ব্যবহার করে সমস্যাযুক্ত। একটি সহজ এবং পর্যাপ্ত সমাধান জন্য এই উত্তর দেখুন ।
পরিবর্তে tr
ব্যবহার করবেন?
tr '\n' ' ' < input_filename
অথবা সম্পূর্ণরূপে নতুন অক্ষর মুছে ফেলুন:
tr -d '\n' < input.txt > output.txt
অথবা যদি আপনার GNU সংস্করণ থাকে (তার দীর্ঘ বিকল্পগুলির সাথে)
tr --delete '\n' < input.txt > output.txt
ফাঁকা লাইন মুছে ফেলার জন্য:
sed -n "s/^$//;t;p;"
ম্যাক ওএস এক্স (ফ্রিবিএসডি সিডি ব্যবহার করে):
# replace each newline with a space
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n/ /g; ta'
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n/ /g' -e ta
Perl সংস্করণ আপনি প্রত্যাশিত উপায় কাজ করে।
perl -i -p -e 's/\n//' file
মতামত হিসাবে নির্দিষ্ট, এটা উল্লেখযোগ্য যে এই সম্পাদনা জায়গায়। -i.bak
আপনার নিয়মিত অভিব্যক্তিটি যতটা স্মার্ট হিসাবে বিবেচিত না হবার ক্ষেত্রে প্রতিস্থাপনের আগে মূল ফাইলের ব্যাকআপ দেয়।
@OP, যদি আপনি একটি ফাইলের নতুন লাইন প্রতিস্থাপন করতে চান তবে আপনি কেবলমাত্র dos2unix (অথবা unix2dox) ব্যবহার করতে পারেন
dos2unix yourfile yourfile
আপনি এই পদ্ধতি ব্যবহার করতে পারেন
sed 'x;G;1!h;s/\n/ /g;$!d'
ব্যাখ্যা
x - which is used to exchange the data from both space (pattern and hold).
G - which is used to append the data from hold space to pattern space.
h - which is used to copy the pattern space to hold space.
1!h - During first line won't copy pattern space to hold space due to \n is
available in pattern space.
$!d - Clear the pattern space every time before getting next line until the
last line.
প্রবাহ:
যখন প্রথম লাইনটি ইনপুট থেকে আসে, এক্সচেঞ্জ তৈরি হয়, তাই 1 স্থান ধরে রাখে এবং \ n প্যাটার্ন স্পেসে আসে, তারপর হোল্ড স্পেসটি প্যাটার্ন স্পেসে যোগ করে এবং তারপরে প্রতিস্থাপন সঞ্চালিত হয় এবং প্যাটার্ন স্পেস মুছে ফেলে।
দ্বিতীয় লাইন বিনিময় সময়, 2 স্থান ধরে রাখা হয় এবং 1 প্যাটার্ন স্পেসে আসে, তারপর প্যাটার্ন স্পেসে G
হোল্ড স্পেস যুক্ত করুন, তারপরে h
প্যাটার্নটি অনুলিপি করুন এবং প্রতিস্থাপন তৈরি এবং মুছে ফেলা হয়। Eof পৌঁছে পর্যন্ত এই অপারেশন অব্যাহত তারপর সঠিক ফলাফল মুদ্রণ।
আমি এই উত্তরটি পোস্ট করেছি কারণ আমি sed
উপরে প্রদত্ত প্রশংসনীয় উদাহরণ দিয়ে চেষ্টা করেছি যা আমার ইউনিক্স বক্সে আমার জন্য কাজ করে না এবং আমাকে ত্রুটি বার্তা দেয় Label too long: {:q;N;s/\n/ /g;tq}
। অবশেষে আমি আমার প্রয়োজনীয়তা তৈরি করেছি এবং তাই এখানে সমস্ত ইউনিক্স / লিনাক্স পরিবেশে কাজ করে যাচ্ছি: -
line=$(while read line; do echo -n "$line "; done < yoursourcefile.txt)
echo $line |sed 's/ //g' > sortedoutput.txt
প্রথম লাইন ফাইল থেকে সমস্ত নতুন লাইন মুছে ফেলা হবে yoursourcefile.txt
এবং একটি একক লাইন উত্পাদন করবে। এবং দ্বিতীয় sed
কমান্ড এটি থেকে সব স্পেস মুছে ফেলা হবে।
sed '1h;1!H;$!d
x;s/\n/ /g' YourFile
এটি বিশাল ফাইলগুলির (বাফার সীমা) জন্য কাজ করে না, তবে ফাইলটি ধরে রাখতে যথেষ্ট মেমরি থাকলে এটি খুব কার্যকর। (সংশোধন H
-> 1h;1!H
@ হিলোজ্যাকের ভাল মন্তব্যের পরে)
পড়ার সময় নতুন লাইন পরিবর্তন করার আরেকটি সংস্করণ (আরো cpu, কম মেমরি)
sed ':loop
$! N
s/\n/ /
t loop' YourFile