sed "s/\(.*\)/\t\1/" $filename > $sedTmpFile && mv $sedTmpFile $filename
আমি এই sed
স্ক্রিপ্টটি tab
প্রতিটি লাইনের সামনে একটি সন্নিবেশ করানোর আশা করছি $filename
তবে তা তা নয়। কিছু কারণে এটি t
পরিবর্তে একটি সন্নিবেশ করছে ।
sed "s/\(.*\)/\t\1/" $filename > $sedTmpFile && mv $sedTmpFile $filename
আমি এই sed
স্ক্রিপ্টটি tab
প্রতিটি লাইনের সামনে একটি সন্নিবেশ করানোর আশা করছি $filename
তবে তা তা নয়। কিছু কারণে এটি t
পরিবর্তে একটি সন্নিবেশ করছে ।
উত্তর:
সমস্ত সংস্করণ sed
বোঝার নয় \t
। পরিবর্তে কেবল একটি আক্ষরিক ট্যাব (োকান ( তারপরে Ctrl- টিপুন )।VTab
\t
বলার জন্য: সমস্ত সংস্করণ প্রকাশের প্রতিস্থাপনের অংশে বুঝতে পারে না (এটি \t
প্যাটার্নের সাথে মিলিত অংশে স্বীকৃত )
ব্যাশ ব্যবহার করে আপনি প্রোগ্রামের মতো কোনও ট্যাব অক্ষর sertোকাতে পারেন:
TAB=$'\t'
echo 'line' | sed "s/.*/${TAB}&/g"
echo 'line' | sed 's/.*/'"${TAB}"'&/g' # use of Bash string concatenation
$'string'
তবে ব্যাখ্যাটির অভাব রয়েছে। প্রকৃতপক্ষে আমি সন্দেহ করি, অত্যন্ত বিশ্রী ব্যবহারের কারণে আপনার সম্ভবত একটি অসম্পূর্ণ বোঝাপড়া রয়েছে (যেমন আমাদের বেশিরভাগ ব্যাশ দিয়ে থাকে)। : নীচের আমার ব্যাখ্যা দেখুন stackoverflow.com/a/43190120/117471
$TAB
একক উদ্ধৃতিগুলির মতো ভেরিয়েবলগুলি প্রসারিত করবে না , সুতরাং আপনার এটির দ্বিগুণ উদ্ধৃতি ব্যবহার করা দরকার।
*
ডাবল কোটসের অভ্যন্তরে ব্যবহার সম্পর্কে সতর্কতা অবলম্বন করুন ... এটিকে গ্লোব হিসাবে বিবেচনা করা হবে, আপনার ইচ্ছাকৃত রেজেক্স হিসাবে নয়।
@sedit সঠিক পথে ছিল তবে ভেরিয়েবলটি সংজ্ঞায়িত করা কিছুটা বিশ্রী।
ব্যাশে এটি করার উপায়টি হল আপনার একক উদ্ধৃত স্ট্রিংয়ের সামনে ডলারের সাইন স্থাপন করা।
$ echo -e '1\n2\n3'
1
2
3
$ echo -e '1\n2\n3' | sed 's/.*/\t&/g'
t1
t2
t3
$ echo -e '1\n2\n3' | sed $'s/.*/\t&/g'
1
2
3
যদি আপনার স্ট্রিংয়ে ভেরিয়েবল সম্প্রসারণ অন্তর্ভুক্ত করা দরকার হয় তবে আপনি উদ্ধৃত স্ট্রিংগুলি একসাথে এভাবে রাখতে পারেন:
$ timestamp=$(date +%s)
$ echo -e '1\n2\n3' | sed "s/.*/$timestamp"$'\t&/g'
1491237958 1
1491237958 2
1491237958 3
বাশ-এর $'string'
কারণে "এএনএসআই-সি সম্প্রসারণ" ঘটে। এবং যে কি আমাদের অধিকাংশ আশা যখন আমরা ভালো জিনিস ব্যবহার করেন \t
, \r
, \n
: ইত্যাদি থেকে https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html#ANSI_002dC-Quoting
ফর্মের শব্দগুলি 'স্ট্রিং' বিশেষভাবে চিকিত্সা করা হয়। শব্দটি স্ট্রিংয়ে প্রসারিত হয় , এএনএসআই সি স্ট্যান্ডার্ড অনুসারে ব্যাকস্ল্যাশ-পলায়নযুক্ত অক্ষর প্রতিস্থাপন করা হয়েছিল। ব্যাকস্ল্যাশ পালানোর ক্রমগুলি যদি উপস্থিত থাকে তবে ডিকোড করা হয়েছে ...
প্রসারিত ফলাফলটি একক-উদ্ধৃত, যেন ডলারের সাইন উপস্থিত ছিল না।
আমি ব্যক্তিগতভাবে মনে করি বাশ এড়ানোর বেশিরভাগ প্রচেষ্টা নিরীহ কারণ বাশিজম এড়ানো আপনার কোডকে * বহনযোগ্য করে তোলে না। (আপনি bash -eu
যদি বাশ এড়ানো এবং ব্যবহার করার চেষ্টা করেন তবে আপনি যদি কোডটি শেবাং করেন তবে আপনার কোডটি কম ভঙ্গুর হবে sh
[যদি আপনি নিখরচায় পসিক্স নিনজা না হন]) তবে এ সম্পর্কে কোনও ধর্মীয় যুক্তি না দিয়ে আমি আপনাকে সেরা দেই * উত্তর.
$ echo -e '1\n2\n3' | sed "s/.*/$(printf '\t')&/g"
1
2
3
* সর্বোত্তম উত্তর? হ্যাঁ, কারণ বেশিরভাগ অ্যান্টি-ব্যাশ শেল স্ক্রিপ্টগুলি তাদের কোডে কী ভুল করবে তার একটি উদাহরণ @ রব্রেকর্ডের উত্তরecho '\t'
হিসাবে ব্যবহার করা হয়েছে । এটি জিএনইউ প্রতিধ্বনির জন্য কাজ করবে, তবে বিএসডি প্রতিধ্বনি নয়। এটি ওপেন গ্রুপ দ্বারা http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_16 এ ব্যাখ্যা করা হয়েছে এবং বাশিজমগুলি এড়াতে সচরাচর কেন ব্যর্থ হয় তার এটি একটি উদাহরণ।
আমি উবুন্টু 12.04 (এলটিএস) এর বাশ শেলের সাথে এরকম কিছু ব্যবহার করেছি:
ট্যাব সহ একটি নতুন লাইন যুক্ত করতে , প্রথম যখন প্রথম মিল হয়:
sed -i '/first/a \\t second' filename
ট্যাব দিয়ে প্রথমে প্রতিস্থাপন করতে , দ্বিতীয় :
sed -i 's/first/\\t second/g' filename
\\t
এবং না \t
।
ব্যবহার $(echo '\t')
। প্যাটার্নটির চারপাশে আপনার উদ্ধৃতিগুলির প্রয়োজন হবে।
যেমন। একটি ট্যাব অপসারণ করতে:
sed "s/$(echo '\t')//"
echo '\t'
2 পৃথক অক্ষর আউটপুট যাচ্ছে। পসিক্স পোর্টেবল উপায়টি হ'ল ব্যবহার করা printf '\t'
। এই কারণেই আমি বলছি: ব্যাশ ব্যবহার না করে আপনার কোডকে পোর্টেবল করার চেষ্টা করবেন না। আপনি যা ভাবেন তার চেয়ে কঠিন। bash
আমাদের মধ্যে বেশিরভাগই করতে পারা যায় এমনটি ব্যবহার করা।
sed
বাস্তবে যখন আপনাকে বাস্তবে ব্যবহার করার দরকার নেই তখন আপনি লাইনের সামনে একটি ট্যাব tabোকাতে চান। কেবলমাত্র এটি মুদ্রণের তুলনায় এই ক্ষেত্রে প্রতিস্থাপন একটি ব্যয়বহুল ক্রিয়াকলাপ, বিশেষত যখন আপনি বড় ফাইলগুলির সাথে কাজ করছেন। এটি রিজেক্স না হিসাবে পড়তেও সহজ।
যেমন awk ব্যবহার
awk '{print "\t"$0}' $filename > temp && mv temp $filename
আমি ম্যাক এ ব্যবহার করেছি:
sed -i '' $'$i\\\n\\\thello\n' filename
sed
সমর্থন করে না \t
, বা অন্যান্য পালানোর ক্রমগুলিও \n
এই বিষয়টির মতো নয়। এটি করার একমাত্র উপায় হ'ল আসলে স্ক্রিপ্টটি ব্যবহার করে ট্যাব অক্ষরটি সন্নিবেশ করানো sed
।
এটি বলেছিল, আপনি পার্ল বা পাইথন ব্যবহার বিবেচনা করতে পারেন। আমি এখানে একটি ছোট পাইথন স্ক্রিপ্ট লিখেছি যে আমি সমস্ত স্ট্রিম রিজেক্সিংয়ের জন্য ব্যবহার করি:
#!/usr/bin/env python
import sys
import re
def main(args):
if len(args) < 2:
print >> sys.stderr, 'Usage: <search-pattern> <replace-expr>'
raise SystemExit
p = re.compile(args[0], re.MULTILINE | re.DOTALL)
s = sys.stdin.read()
print p.sub(args[1], s),
if __name__ == '__main__':
main(sys.argv[1:])
বিএসডি সেডের পরিবর্তে আমি পার্ল ব্যবহার করি:
ct@MBA45:~$ python -c "print('\t\t\thi')" |perl -0777pe "s/\t/ /g"
hi
আমি মনে করি অন্যদের অন্যান্য পন্থা (জন্য পর্যাপ্তরূপে এই ব্যাখ্যা আছে sed
, AWK
ইত্যাদি)। তবে, আমার-নির্দিষ্ট bash
উত্তরগুলি (ম্যাকোস হাই সিয়েরা এবং সেন্টোস 6/7 এ পরীক্ষিত) অনুসরণ করে।
1) ওপি যদি তারা মূলত প্রস্তাবিত অনুরূপ অনুসন্ধান-এবং-প্রতিস্থাপন পদ্ধতিটি ব্যবহার করতে চায়, তবে আমি perl
নীচের মত এটির জন্য ব্যবহারের পরামর্শ দেব । দ্রষ্টব্য: Regex জন্য প্রথম বন্ধনী আগে ব্যাকস্ল্যাশ প্রয়োজন নেই হওয়া উচিত, এবং এই কোড লাইন প্রতিফলিত কিভাবে $1
ছাড়া ব্যবহার করা উত্তম \1
সঙ্গে perl
প্রতিকল্পন অপারেটর (যেমন প্রতি পার্ল 5 ডকুমেন্টেশন )।
perl -pe 's/(.*)/\t$1/' $filename > $sedTmpFile && mv $sedTmpFile $filename
২) তবে, ঘোস্টডোগ by৪ দ্বারা চিহ্নিত হিসাবে , যেহেতু কাঙ্ক্ষিত অপারেশনটি আসলে প্রতিটি লাইনটির শুরুতে একটি ট্যাব যুক্ত করে ইনপুট / টার্গেট ফাইল ( $filename
) এ টিএমপি ফাইলটি পরিবর্তন করার আগে , আমি perl
আবার সুপারিশ করব তবে নীচের পরিবর্তনের সাথে (গুলি):
perl -pe 's/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename
## OR
perl -pe $'s/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename
3) অবশ্যই, টিএমপি ফাইলটি অতিমাত্রায় প্রোথিত , তাই কেবল 'স্থানে' ( -i
পতাকা যুক্ত করা) সবকিছু করা এবং জিনিসগুলিকে আরও মার্জিত ওয়ান-লাইনারে সরল করে তোলা ভাল with
perl -i -pe $'s/^/\t/' $filename