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- Vतब Tab)।
\tको अभिव्यक्ति के प्रतिस्थापन भाग में समझ में नहीं आता है (यह \tपैटर्न मिलान भाग में ठीक पहचाना गया है)
बैश का उपयोग करके आप एक TAB वर्ण प्रोग्राम की तरह सम्मिलित कर सकते हैं:
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सिंगल कोट्स के अंदर वैरिएबल का विस्तार नहीं करेगा , इसलिए आपको इसे डबल कोट्स का उपयोग करने की आवश्यकता होगी।
*दोहरे उद्धरण चिह्नों का उपयोग करने के बारे में सावधान ... यह एक ग्लोब के रूप में माना जाएगा, न कि आपके द्वारा बताए गए रीगेक्स के रूप में।
@ हेरिटेज सही रास्ते पर था, लेकिन एक चर को परिभाषित करना थोड़ा अजीब है।
बैश में ऐसा करने का तरीका आपके एकल उद्धृत स्ट्रिंग के सामने एक डॉलर का चिह्न रखना है।
$ 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
फॉर्म $ 'स्ट्रिंग' के शब्दों को विशेष रूप से व्यवहार किया जाता है। यह शब्द ANSI C मानक द्वारा निर्दिष्ट बैकस्लैश-एस्कैप्ड वर्णों के साथ स्ट्रिंग में फैलता है । बैकस्लैश एस्केप सीक्वेंस, अगर मौजूद हैं, तो डिकोड हो गए हैं ...
विस्तारित परिणाम एकल-उद्धृत है, जैसे कि डॉलर का चिह्न मौजूद नहीं था।
मुझे व्यक्तिगत रूप से लगता है कि बैश से बचने के अधिकांश प्रयास मूर्खतापूर्ण होते हैं क्योंकि बैश से बचने के लिए अपने कोड को पोर्टेबल नहीं बनाते हैं। (आपका कोड कम भंगुर होगा यदि आप इसे शेबंग bash -euसे करते हैं यदि आप बैश से बचने और उपयोग करने की कोशिश करते हैं sh[जब तक कि आप एक पूर्ण पॉज़िक्स निंजा नहीं हैं]।) लेकिन इसके बजाय इसके बारे में एक धार्मिक तर्क है, मैं आपको सिर्फ सर्वश्रेष्ठ दूँगा। * उत्तर।
$ echo -e '1\n2\n3' | sed "s/.*/$(printf '\t')&/g"
1
2
3
* सबसे बढ़िया उत्तर? हाँ, क्योंकि ज्यादातर विरोधी पार्टी खोल scripters उनके कोड में गलत क्या करना होगा का एक उदाहरण इस्तेमाल होता है echo '\t'के रूप में @ robrecord का जवाब । यह GNU इको के लिए काम करेगा, लेकिन BSD इको के लिए नहीं। इसे http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_16 पर द ओपन ग्रुप द्वारा समझाया गया है और यह इस बात का उदाहरण है कि क्यों बशर्ते से बचने की कोशिश असफल हो रही है।
मैंने Ubuntu 12.04 (LTS) पर बैश शेल के साथ कुछ इस तरह का उपयोग किया है:
टैब के साथ एक नई लाइन जोड़ने के लिए , दूसरा जब पहली बार मिलान किया जाता है:
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 अलग-अलग पात्रों का उत्पादन करने जा रहा है। POSIX पोर्टेबल तरीका उपयोग करना है printf '\t'। यही कारण है कि मैं कहता हूं: बैश का उपयोग न करके अपने कोड को पोर्टेबल बनाने की कोशिश न करें। आपके विचार से यह कठिन है। उपयोग करना bashसबसे पोर्टेबल चीज़ है जो हम में से अधिकांश कर सकते हैं।
sedवास्तविक स्थिति में होने पर आपको प्रतिस्थापन करने के लिए उपयोग करने की आवश्यकता नहीं होती है, आप केवल पंक्ति के सामने एक टैब सम्मिलित करना चाहते हैं। इस मामले के लिए प्रतिस्थापन एक महंगा ऑपरेशन है क्योंकि इसे केवल प्रिंट करने की तुलना में, खासकर जब आप बड़ी फ़ाइलों के साथ काम कर रहे हैं। यह पढ़ने में आसान है, क्योंकि यह रेगेक्स नहीं है।
जैसे कि 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:])
BSD sed के बजाय, मैं perl का उपयोग करता हूं:
ct@MBA45:~$ python -c "print('\t\t\thi')" |perl -0777pe "s/\t/ /g"
hi
मुझे लगता है कि दूसरों के अन्य तरीकों (के लिए पर्याप्त रूप से इस स्पष्ट किया है sed, AWK, आदि)। हालाँकि, मेरे bashविशिष्ट जवाब (macOS उच्च सिएरा और CentOS 6/7 पर परीक्षण) का पालन करें।
1) अगर ओपी मूल रूप से प्रस्तावित की तरह एक खोज-और-प्रतिस्थापित विधि का उपयोग करना चाहता था, तो मैं इसके perlलिए उपयोग करने का सुझाव दूंगा , इस प्रकार। नोट: रेगेक्स के लिए कोष्ठक से पहले बैकस्लैश आवश्यक नहीं होना चाहिए, और यह कोड लाइन दर्शाती है कि प्रतिस्थापन ऑपरेटर (जैसे प्रति पर्ल 5 प्रलेखन ) के साथ $1उपयोग करना बेहतर है ।\1perl
perl -pe 's/(.*)/\t$1/' $filename > $sedTmpFile && mv $sedTmpFile $filename
2) हालांकि, जैसा कि ghostdog74 द्वारा बताया गया है , चूंकि वांछित ऑपरेशन वास्तव में इनपुट / लक्ष्य फ़ाइल ( ) में tmp फ़ाइल को बदलने से पहले प्रत्येक पंक्ति की शुरुआत में एक टैब जोड़ने के लिए है $filename, मैं perlफिर से सिफारिश करूंगा लेकिन निम्नलिखित संशोधन के साथ (ओं):
perl -pe 's/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename
## OR
perl -pe $'s/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename
3) बेशक, tmp फ़ाइल है ज़रूरत से ज़्यादा है, तो यह सिर्फ 'जगह में' सब कुछ करना (जोड़ने के लिए बेहतर है -iके साथ एक और अधिक सुरुचिपूर्ण एक लाइनर करने के लिए ध्वज) और सरल बातें
perl -i -pe $'s/^/\t/' $filename