केवल 'tr' का उपयोग करके एक के साथ कई स्थान बदलें


71

मेरे पास एक फाइल है f1.txt:

ID     Name
1      a
2         b
3   g
6            f

रिक्त स्थान की संख्या निश्चित नहीं है। केवल एक जगह का उपयोग करके सभी सफेद रिक्त स्थान को बदलने का सबसे अच्छा तरीका क्या है tr?

अभी तक मेरे पास इतना ही है:

cat f1.txt | tr -d " "

लेकिन आउटपुट है:

IDName
1a
2b
3g
6f

लेकिन मैं चाहता हूं कि यह इस तरह दिखे:

ID Name
1 a
2 b
3 g
6 f

कृपया कोशिश करें और बचें sed


6
तलछट से बचने के लिए इतना महत्वपूर्ण क्यों है? जो भी काम करें उसका उपयोग करें!
डेविड रिचरबी

7
क्योंकि मुझे पता है कि यह कैसे करना है sed। अन्य तरीके जानना चाहते हैं
:)

जवाबों:


106

साथ tr, sक्विज़ रिपीट विकल्प का उपयोग करें :

$ tr -s " " < file
ID Name
1 a
2 b
3 g
6 f

या आप एक awkसमाधान का उपयोग कर सकते हैं:

$ awk '{$2=$2};1' file
ID Name
1 a
2 b
3 g
6 f

जब आप रिकॉर्ड में कोई फ़ील्ड बदलते हैं, तो awkपुनर्निर्माण करते हैं $0, सभी फ़ील्ड लेते हैं और उन्हें एक साथ अलग करते हैं OFS, जो डिफ़ॉल्ट रूप से एक स्थान होता है।

यह अंतरिक्ष और टैब (और संभवतः अन्य रिक्त वर्णों के स्थान और कार्यान्वयन के आधार पर awk) के दृश्यों को एक स्थान पर निचोड़ देगा , लेकिन प्रत्येक पंक्ति के प्रमुख और अनुगामी रिक्त स्थान को भी हटा देगा।


1
यह एक बेहतरीन उपाय भी है। । । मुझे नहीं पता कि अब किसे चुनना है: / @Gnouc
gkmohit

किसी भी समाधान को बेझिझक चुनें जो आपको पसंद है और यह आपके लिए काम करता है। एक नोट जो मेरा समाधान @ पॉलिम के उत्तर के साथ अलग है।
congonglm

1
:)) वाह! @ ग्नुक का उत्तर वास्तव में गतिशील है, क्योंकि वह उपयोग करता है awk, वह कुछ भी कर सकता है। आप उसका समाधान भी स्वीकार कर सकते हैं। बस एक बात: Gnouc क्या आप संभवतः समझा सकते हैं कि आपके कमांड में awk फॉर्मेट क्या करता है? क्या आप टैब / स्पेस भी जोड़ सकते हैं ताकि आउटपुट अज्ञात के अपेक्षित आउटपुट के अनुरूप हो?
पॉलीम

1
@ पॉलीम: अज्ञात के अंतिम संपादन के साथ, वह केवल एक स्थान चाहता है, जैसे आउटपुट नहीं column -tकरता है। के लिए स्पष्टीकरण जोड़ें awk
क्यूंग्लम

4
यहाँ एक छोटा सा अंतर है। trएक पंक्ति के अंत में एक स्थान के साथ दो स्थानों को प्रतिस्थापित करेगा। awkसभी अनुगामी रिक्त स्थान को निकाल देगा।
ऐनी वैन रोसुम

19

बस उपयोग करें column:

column -t inputFile

आउटपुट:

ID  Name
1   a
2   b
3   g
6   f

अद्भुत और एक त्वरित उत्तर :)
gkmohit

1
@ ज्ञात महान सेवा में होना :)!
पॉलीम

1
@Gnouc वाह कूल, कॉलम भी एक फाइल को तर्क के रूप में लेता है। अच्छा धन्यवाद!
पॉलीम

अगर मैं चाहूं तो मैं दूसरा कॉलम कैसे प्राप्त कर सकता हूं? मैंने कोशिश की, column -t f1.txt | cut -d " " -f2 लेकिन मुझे उम्मीद थी कि कोई समाधान नहीं है
gkmohit

2
तब awk का उपयोग करें: column -t file | awk '{print $2}'केवल दूसरे कॉलम को प्रिंट करता है
polym

8

यदि आप "सफ़ेद स्थान" को निचोड़ना चाहते हैं, तो आप tr के पूर्व-निर्धारित वर्ण सेट ": रिक्त:" (क्षैतिज व्हाट्सएप टैब और स्थान) या ": स्थान:" (क्रियात्मक व्हाट्सएप) का उपयोग करना चाहेंगे:

/bin/echo -e  "val1\t\tval2   val3" | tr -s "[:blank:]"

उदाहरण Red Hat 5 (GNU tr) पर चलाए गए।

मेरे मामले में मैं सभी व्हाट्सएप को एक ही स्थान पर सामान्य करना चाहता था, ताकि मैं अंतरिक्ष यात्री के रूप में भरोसा कर सकूं।

जैसा कि dastrobu की दूसरी टिप्पणी के अनुसार मैंने मैन पेज में शब्दों को याद किया:

 -s uses the last specified SET, and occurs after translation or deletion.

यह हमें पहली ट्रे को खत्म करने की अनुमति देता है। कुडोन्स ने मेरी घनीभूतता के लिए अपने दर्शकों के लिए स्काउट किया।

पहले, Redis config से पोर्ट पार्सिंग। फ़ाइल:

grep "^port" $redisconf | tr "[:blank:]" " " | tr -s "[:blank:]"  | cut -d" " -f2

SET2 के बाद निचोड़ के साथ निर्दिष्ट किया जा रहा है:

grep "^port" $redisconf | tr -s "[:blank:]" " " | cut -d" " -f2

आउटपुट:

6379

अधिक जानकारी के लिए व्हाट्सएप की बारीकियों को कवर करना

यह प्रदर्शित करें कि जहां अकेले निचोड़ विफल रहता है, जब क्रमिक मिश्रित वर्ण जो [: ब्लैंक:] वर्ण वर्ग में शामिल होते हैं:

 /usr/bin/printf '%s \t %s' id myname | tr -s "[:blank:]"  | od -cb
0000000   i   d      \t       m   y   n   a   m   e
        151 144 040 011 040 155 171 156 141 155 145
0000013

नोट: प्रिंटफ़ प्रारूप में मेरे दो स्ट्रिंग फ़ील्ड 1 स्थान, 1 टैब, 1 स्थान द्वारा अलग किए गए हैं। निचोड़ के बाद यह क्रम अभी भी मौजूद है। ऑक्टल डंप के आउटपुट में यह एससीआई अनुक्रम 040 011 040 द्वारा दर्शाया गया है।


1
क्या आपको वास्तव में जरूरत है tr "[:blank:]" " " | tr -s "[:blank:]"? मुझे लगता है कि पहला भाग पर्याप्त होगा, अर्थात tr "[:blank:]" " "जब से यह व्हाट्सएप को सामान्य करता है और पहले से ही प्रतिस्थापन करता है। मैन पेज से: "वर्णों की कई घटनाओं को निचोड़ें [...] यह सभी विलोपन और अनुवाद पूरा होने के बाद होता है।"
डेस्ट्रोबू

2
इसलिए "tr -s "[: blank:]" "" इसे करना चाहिए यह पहले रिक्त स्थान के लिए सभी रिक्त स्थान का अनुवाद करता है और फिर रिक्त स्थान को निचोड़ता है। दूसरे ´tr´ के लिए कोई ज़रूरत नहीं है।
डेस्ट्रोबू

1
मैंने कोशिश की printf 'ID \t Name\n' | tr -s "[:blank:]" " " | od -cb(जैसा कि @dastrobu ने सुझाव दिया था) और मुझे आउटपुट के रूप में ID Name\n( एक स्थान के साथ ) मिला । क्या आपने वास्तव में इसका प्रयास किया था, @ user3183018?
स्कॉट

1
ठीक है, मुझे फिर से यह कहने की कोशिश करें। मैंने किया printf 'ID␣\t␣Name\n' | tr -s "[:blank:]" "␣"  (जैसा कि @dastrobu द्वारा सुझाया गया है), जहां एक स्थान का प्रतिनिधित्व करता है, और मुझे ID␣Name\nआउटपुट के रूप में (एक स्थान के साथ) मिला है । यह बिल्कुल "पोर्ट <SPACE> <TAB> <SPACE> 6379" के आपके उदाहरण के समान है, सिवाय इसके कि मैंने प्रश्न से हेडिंग स्ट्रिंग्स का उपयोग किया है। मुझे आश्चर्य है कि क्या आपने tr -s "[:blank:]"(अंतिम "␣"तर्क के बिना ) कोशिश की  ।
स्कॉट

1
जब मैं करता हूं printf 'ID \t Name\n' | od -cb, तो यह वही दिखाता है जो यह माना जाता है: ID ⁠  \t ⁠  N a m e \n(यानी,  ID 040 011 040 N a m e\n)। इस बीच, अपने स्वयं के साक्ष्य द्वारा, आप बिल्कुल त्रुटि कर रहे हैं जो मैंने अनुमान लगाया था कि आप थे: आप चला रहे हैं tr -s "[:blank:]"(यानी,  trएक विकल्प और  एक तर्क के साथ), कमांड के बजाय @dastrobu और मैंने अब चार बार प्रस्तुत किया है: tr -s '[:blank:]' '␣'(यानी,  trएक विकल्प और  दो तर्कों के साथ )।
स्कॉट

5

किसे प्रोग्राम (शेल के अलावा) की आवश्यकता है?

while read a b
do
    echo "$a $b"
done < f1.txt

यदि आप चाहते हैं कि दूसरे कॉलम में मान पॉलिम के columnउत्तर में हों, तो printfइसके बजाय उपयोग करें echo:

while read a b
do
    printf '%-2s %s\n' "$a" "$b"
done < f1.txt

1
पहली जगह में, जब ट्र के साथ तुलना की जाती है - यह एक बहुत ही कमजोर सुझाव दक्षता-वार है जब तक कि इनपुट बहुत छोटा trनहीं है, लेकिन यह आह्वान करने के लिए कितना काम लेता है - यह उल्लेख नहीं है कि यह कितना अधिक काम है। अंतिम, क्या आप यह नहीं कहेंगे कि यह पोस्ट वास्तव में पूछे गए प्रश्न का उत्तर नहीं देता है? केवल ट्रे का उपयोग करके सभी सफेद रिक्त स्थान को एक स्थान से बदलने का सबसे अच्छा तरीका क्या है?
चाटुकार

1
और इसके अलावा - क्या आप अधिक आसानी से बस के साथ कुछ नहीं कर सकते $IFS? शायद पसंद है IFS=' <tab>' set -f ; echo $(cat <file):?
चाटुकार

2

यह एक पुराना सवाल है और कई बार हल किया गया है। बस पूर्णता के लिए: मेरे पास एक सिमिलर मुद्दा था, लेकिन पाइप से एंटोथेर कार्यक्रम तक लाइनों को पारित करना चाहता था। मैंने xargs का इस्तेमाल किया ।

-L max-lines
   Use at most max-lines nonblank input lines per command line.
   Trailing blanks cause an input line to be logically continued 
   on the next input line.  Implies -x.

ऐसा cat f1.txt | xargs -L1लगता है कि आप क्या चाहते हैं।

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