रहस्यमय तरीके से टैब्स की सरल सेड रिप्लेसमेंट


43

यह वास्तव में सरल होना चाहिए, लेकिन किसी कारण से यह काम नहीं कर रहा है:

sed -i.bak -E 's/\t/  /' file.txt

टैब वर्णों को बदलने के बजाय, यह tवर्णों को प्रतिस्थापित कर रहा है। मैंने इसके बारे में हर बदलाव की कोशिश की है, जिसके बारे में मैं सोच सकता हूँ, उद्धृत करने के साथ खेल रहा हूँ, आदि। मैंने Googled और सभी को समान समान भावों का उपयोग करते हुए पाया है और वे उनके लिए काम करते हैं।

-Eएक ओएस एक्स बात है। मैंने सोचा था कि असफलता ओएस एक्स के कुछ अजीब विचित्रता का परिणाम हो सकती है sed, इसलिए मैंने रूबी के साथ (बिना -i), और उसी परिणाम के साथ कोशिश की:

ruby -pe '$_.gsub!(/\t/,"  ")' < file.txt > file.new

मैं ओएस एक्स, और iTerm पर बैश 3.2.51 का उपयोग कर रहा हूं, हालांकि मैं यह नहीं देख सकता कि उनमें से कोई भी बहुत प्रासंगिक कैसे हो सकता है। मैंने कोई भी अजीब पर्यावरण चर निर्धारित नहीं किया है, हालांकि मैं कोई भी पोस्ट कर सकता हूं जो आपको लगता है कि प्रासंगिक हो सकता है।

क्या गलत हो सकता है?

अद्यतन करें : जब मैंने रूबी संस्करण की कोशिश की थी, तब मैंने कुछ अन्य गलती या टाइपो किया होगा, क्योंकि गिल्स बताते हैं कि यहकाम करता है (और मैंने कभी उसे गलत नहीं किया है!)। मुझे यकीन नहीं है कि क्या हुआ, लेकिन मुझे पूरा यकीन है कि यह मेरी गलती रही होगी।


5
हो सकता है आप को बदलने के लिए प्रयास करना चाहिए \tमें sedसे बयान CTRL-V<TAB>जहां <TAB>टैब कुंजी है और CTRL-Vनियंत्रण कुंजी और है vएक साथ दबाया।
अप्रत्यक्ष जूल 18'14

अगर माणिक को गलत उत्तर मिल रहा है, तो यह आपकी regexp लाइब्रेरी हो सकती है। (मैंने आपके दोनों आदेशों का परीक्षण किया है, और दोनों टैब को 2 स्थानों के साथ प्रतिस्थापित करते हैं।) ऐसा तब होता है जब आप Gnu sed को स्थापित करते हैं, तो यह उम्मीद है कि यह सही लाइब्रेरी भी स्थापित करेगा।
ctrl-alt-delor-

जवाबों:


64

\tSed में टैब वर्ण के लिए सिंटैक्स मानक नहीं है। यह पलायन एक GNU सेड विस्तार है । आपको बहुत सारे उदाहरण ऑनलाइन मिलते हैं जो इसका उपयोग करते हैं क्योंकि बहुत सारे लोग GNU sed का उपयोग करते हैं (यह गैर-एम्बेडेड लिनक्स पर sed कार्यान्वयन है)। लेकिन OS X sed , अन्य * BSD sed की तरह, \tटैब के लिए समर्थन नहीं करता है और इसके बजाय \tबैकस्लैश का अर्थ करता है t

कई समाधान हैं, जैसे:

  • शाब्दिक टैब वर्ण का उपयोग करें।

    sed -i.bak 's/  /  /' file.txt
    
  • टैब वर्ण का उपयोग trया printfउत्पादन करने के लिए।

    sed -i.bak "s/$(printf '\t')/  /" file.txt
    sed -i.bak "s/$(echo a | tr 'a' '\t')/  /" file.txt
    
  • बैश के स्ट्रिंग सिंटैक्स का प्रयोग करें जिससे बैकलैश बच जाता है

    sed -i.bak $'s/\t/  /' file.txt
    
  • पर्ल, पायथन या रूबी का उपयोग करें। रूबी स्निपेट जो आपने पोस्ट किया है वह काम करता है।


सीक स्क्रिप्ट के लिए जो एक ...sedस्क्रिप्ट में शामिल हैं ( -fविकल्प के माध्यम से उपयोग किया जाता है), शाब्दिक टैब वर्ण मेरे लिए एकमात्र संभावना है। जब इसे विम के साथ संपादित किया जाए, तो set noexpandtabयह महत्वपूर्ण है।
तोबियास

चेतावनी: केवल उस "शाब्दिक टैब वर्ण" तकनीक का उपयोग करें यदि आप चाहते हैं कि आपका सहकर्मी आपके पीछे वापस आए और बाद में आपकी स्क्रिप्ट को तोड़ दे। केवल उस trतकनीक का उपयोग करें यदि आप चाहते हैं कि आपका सहकर्मी आपकी पटकथा पढ़ते समय आपके चेहरे पर छुरा घोंपे।
ब्रूनो ब्रोंस्की

क्या कोड के दूसरे ब्लॉक में दूसरा दोहरा-उद्धरण चिह्न गलत है? मुझे इसे उस स्थान पर ले जाना था जहां वर्तमान में समापन एकल-उद्धरण है।
एलेन स्पार्टस

बैश स्ट्रिंग सिंटैक्स के लिंक के लिए धन्यवाद ... मुझे कोई पता नहीं था (और यह सबसे अच्छा विकल्प है, IMHO)।
लेविग्रोकर

sed $'s/<regex>/\t/' file.txtसम्मिलित करने के लिए काम करता है, लेकिन $लगता है कि जब मैं अपने प्रतिस्थापन में regex का हिस्सा शामिल करने की कोशिश करता हूं, तो मेरी स्क्रिप्ट को तोड़ने की कोशिश करता है, अर्थात sed $'s,\(ontology/[0-9]\+\),\t\txxx\1xxx\t\t,'`xxxxxx` को मेरे अपेक्षित मैच मान के साथ `` देता है। क्या \1बैश के स्ट्रिंग सिंटैक्स का उपयोग करते समय एक समान है ? संपादित करें: xxx <U + 231C> xxx के मध्य में U + 231C यूनिकोड वर्ण होना चाहिए।
जोश

14

एक बैश विशिष्ट उद्धरण का उपयोग करें जो आपको सी की तरह तार का उपयोग करने की अनुमति देता है, ताकि एक वास्तविक टैब चरित्र को sed में पारित किया जा सके, न कि एक अपवाद के रूप में:

sed -i.bak -E $'s/\t/  /' file.txt

1
यह भी कहा जाता है कि "एएनएसआई-सी" को उद्धृत करना अगर अन्य लोग इसके बारे में अधिक जानकारी देखना चाहते हैं।
वारबैंक

2
किसी भी बोर्न शेल पर काम करने लगता है, नॉन-बैश यूनिक्स पर भी काम करता है। हालांकि csh-varants पर काम नहीं करता है।
jornane

1

जैसा कि कहा गया है, सभी sedकार्यान्वयन \tक्षैतिज टैब के रूप में अंकन का समर्थन नहीं करते हैं ।

आप आसानी से अपना प्रतिस्थापन प्राप्त कर सकते हैं:

 perl -pi.old -e 's{\t+}{ }g' file.txt

यह एक स्वस्थानी प्रतिकृति करता है जो आपकी मूल फ़ाइल को "* .old" के रूप में संरक्षित करता है। पर्ल क्लासिक /को अभिव्यक्ति के लिए वैकल्पिक रूप से अधिक पठनीय बनाने की अनुमति देता है (यानी "लीनिंग टूथपिक सिंड्रोम" से रहित)।

+कहते हैं एक टैब वर्ण के एक या अधिक repetitions प्रतिस्थापित किया जाना है। gसंशोधक प्रत्येक पंक्ति के अंत में वैश्विक प्रतिस्थापन सक्षम बनाता है।


1
sed -i $'s/\t/  /g' file.txt 

मेरे लिए OS X पर काम करता है और वही कमांड है जिसका उपयोग मैं हर समय लिनक्स पर करता हूं।


ध्यान दें कि यह हर पंक्ति के सभी टैब को बदल देता है जबकि ओपी केवल पहले को प्रतिस्थापित करने का इरादा रखता है (वे जिस कमांड का उपयोग करते हैं उसे देखते हुए)।
Kusalananda

0

आप echoअंदर भी उपयोग कर सकते हैं sed:

sed -i "s/$(echo '\t')//g"


ध्यान दें कि echo '\t'सिर्फ \tकुछ गोले के कार्यान्वयन में उत्पादन होगा echo
Kusalananda

0

यदि आप OS X पर एक से अधिक शक्तिशाली sed(समर्थन \tऔर अधिक) चाहते हैं , तो GNU sed स्थापित करें ।


चूंकि यह रूबी के साथ काम नहीं करता था, मुझे यकीन नहीं है कि मैं यह क्यों कहूंगा कि ओएस एक्स की sedसमस्या है। क्या आपके पास यह विश्वास करने का कोई कारण है कि समस्या क्या है? अगर मुझे लगता है कि यह समस्या का समाधान होगा, तो मुझे विश्वास था कि मुझे GNU सेड को स्थापित करने में खुशी होगी, लेकिन ऐसा लगता है कि मैंने बहुत अधिक शासन किया है।
आइकनोकॉस्ट

रूबी के साथ, आपको केवल एक बैकस्लैश का उपयोग करना होगा:ruby -pe '$_.gsub!(/\t/," ")' < file.txt
vinc17

0

यदि यह आवश्यक है bashया zshशेल के रूप में ठीक है , तो यह सबसे आसान उपाय है जो मैं सोच सकता हूं:

sed "s/$(echo -n -e "\t")/ /" file.txt

हालाँकि, ध्यान दें कि echoझंडे ( -nऔर -e) POSIX में अपरिभाषित हैं, इसलिए POSIX अनुरूप शेल को थिसिस फ़्लैग को समझने की आवश्यकता नहीं है, फिर भी कई संगतता कारणों के लिए होगा।


-1

मुझे आश्चर्य है कि किसी ने भी इसका बहुत ही सरल उपाय नहीं सुझाया है: sed -i.bak -E 's/\\\t/ /' file.txt यह चाल चलनी चाहिए।

आपको भागने से बचने की आवश्यकता है (इसलिए 3 \ _) सेड को यह समझने की अनुमति दें कि आप नियमित अभिव्यक्ति में \ t वर्ण का उपयोग करने की कोशिश कर रहे हैं जब सब कुछ प्रतिस्थापित किया जाता है ...


क्यों तीन backslashes विशेष रूप से?
माइकल होमर

3
अगर मैं जीएनयू का उपयोग करता हूं sed, तो एक \ पर्याप्त है, क्योंकि कोई भी पलायन आवश्यक नहीं है। समस्या यह है कि बीएसडी sedटैब के लिए इस सिंटैक्स का समर्थन नहीं करता है।
इकोनॉस्टल

मेरे एल कैपिटन पर काम नहीं करता है।
फ्रैंकलिन यू

-4

इसने मेरे लिए काम किया।

sed -e 's / [\ t] / / g'


3
ऐसा इसलिए है क्योंकि आप GNU का उपयोग करते हैं sed। यह वह नहीं है जो ओपी उपयोग करता है।
Kusalananda
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.