'कट' कमांड को उसी क्रमिक सीमांकक के रूप में एक कैसे बनाया जाए?


307

मैं कॉलम-आधारित, 'स्पेस-एडजस्टेड टेक्स्ट स्ट्रीम' से एक निश्चित (चौथा) फील्ड निकालने की कोशिश कर रहा हूं। मैं cutनिम्नलिखित तरीके से कमांड का उपयोग करने की कोशिश कर रहा हूं :

cat text.txt | cut -d " " -f 4

दुर्भाग्य से, cutकई स्थानों को एक सीमांकक के रूप में नहीं माना जाता है। मैं जाग के माध्यम से पाइप कर सकता था

awk '{ printf $4; }'

या sed

sed -E "s/[[:space:]]+/ /g"

रिक्त स्थान को ढहाने के लिए, लेकिन मैं जानना चाहूंगा कि क्या मूल तरीके से cutऔर कई सीमांतों से निपटने का कोई तरीका है ?


12
AWK जाने का रास्ता है।
अगली सूचना तक रोक दिया गया।

जवाबों:


545

प्रयत्न:

tr -s ' ' <text.txt | cut -d ' ' -f4

से trआदमी पेज:

-s, --squeeze-repeats दोहराया वर्ण के प्रत्येक इनपुट अनुक्रम को प्रतिस्थापित करता है
                        यह SET1 में एकल घटना के साथ सूचीबद्ध है
                        उस चरित्र का

24
यहां कोई जरूरत नहीं cat। आप < text.txtसीधे पास कर सकते थे tren.wikipedia.org/wiki/Cat_%28Unix%29#Useless_use_of_cat
arielf

1
यह सुनिश्चित नहीं है कि यह किसी भी सरल है, लेकिन आप मर्ज करने जा रहे हैं, आप कट को काट सकते हैं -dऔर सीधे कई पात्रों से टैब में अनुवाद कर सकते हैं । उदाहरण के लिए: मैं यहां अपने प्रदर्शन को स्वचालित रूप से निर्यात करने का तरीका ढूंढ रहा था:who am i | tr -s ' ()' '\t' | cut -f5
सिंह

यह awk solution के विपरीत अग्रणी / अनुगामी व्हाट्सएप (जो कि वांछित नहीं भी हो सकता है, लेकिन आमतौर पर नहीं है) को दूर नहीं करता है। जाग समाधान भी अधिक पठनीय और कम क्रिया है।
n.illillou

-1 चेतावनी: इस तरह एक व्यक्ति के रूप में पूर्ववर्ती समय के दौरान भी ऐसा नहीं है। तुलना करें echo "a b c" | cut -d " " -f2-,echo "a b c" | tr -s " " | cut -d " " -f2-
user541686

96

जैसा कि आप अपने प्रश्न में टिप्पणी करते हैं, awkवास्तव में जाने का रास्ता है। उपयोग करने के लिए रिक्त स्थान को निचोड़नाcut संभव है tr -s, केव के उत्तर के रूप में ।

हालांकि मुझे भविष्य के पाठकों के लिए सभी संभावित संयोजनों के माध्यम से जाना चाहिए। स्पष्टीकरण परीक्षण अनुभाग में हैं।

tr | कट गया

tr -s ' ' < file | cut -d' ' -f4

awk

awk '{print $4}' file

दे घुमा के

while read -r _ _ _ myfield _
do
   echo "forth field: $myfield"
done < file

sed

sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' file

टेस्ट

इस फ़ाइल को देखते हुए, आज्ञाओं का परीक्षण करें:

$ cat a
this   is    line     1 more text
this      is line    2     more text
this    is line 3     more text
this is   line 4            more    text

tr | कट गया

$ cut -d' ' -f4 a
is
                        # it does not show what we want!


$ tr -s ' ' < a | cut -d' ' -f4
1
2                       # this makes it!
3
4
$

awk

$ awk '{print $4}' a
1
2
3
4

दे घुमा के

यह खेतों को क्रमिक रूप से पढ़ता है। उपयोग करके _हम संकेत देते हैं कि यह इन क्षेत्रों को अनदेखा करने के लिए "जंक वैरिएबल" के रूप में एक फेंकने योग्य चर है। इस तरह, हम $myfieldफ़ाइल में 4 वें क्षेत्र के रूप में संग्रहीत करते हैं, कोई फर्क नहीं पड़ता कि उनके बीच के रिक्त स्थान हैं।

$ while read -r _ _ _ a _; do echo "4th field: $a"; done < a
4th field: 1
4th field: 2
4th field: 3
4th field: 4

sed

यह तीन समूहों को पकड़ता है और कोई रिक्त स्थान नहीं है ([^ ]*[ ]*){3}। फिर, यह 4 क्षेत्र के रूप में एक स्थान तक आने वाले जो कुछ भी पकड़ता है, वह अंत में इसके साथ मुद्रित होता है \1

$ sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' a
1
2
3
4

2
awkकेवल सुरुचिपूर्ण और सरल नहीं है, यह वीएमवेयर ईएसएक्सआई में भी शामिल है, जहां trगायब है।
user121391

2
@ user121391 उपयोग करने का एक और कारण awk!
फेडोरक्वी 'एसओ ने'

@fedorqui मैंने "जंक चर" के रूप में अंडरस्कोर के बारे में कभी नहीं सुना है। क्या आप इस पर कोई अधिक जानकारी / संदर्भ प्रदान कर सकते हैं?
ब्रायनकैन

1
@BryKKan मुझे इसके बारे में ग्रेग के बारे में पता चला कि मैं एक फ़ाइल (डेटा स्ट्रीम, चर) लाइन-बाय-लाइन (और / या फ़ील्ड-बाय-फ़ील्ड) कैसे पढ़ सकता हूं? : कुछ लोग खेतों को नजरअंदाज करने के लिए थ्रोअवे वेरिएबल _ को "जंक वैरिएबल" के रूप में इस्तेमाल करते हैं। यह (या वास्तव में किसी भी चर) का उपयोग एक ही readआदेश में एक से अधिक बार किया जा सकता है , अगर हमें परवाह नहीं है कि इसमें क्या जाता है । यह कुछ भी हो सकता है, यह सिर्फ इतना है कि यह किसी तरह junk_varया की बजाय मानक बन गया whatever:)
फेडोरक्वी 'एसओ स्टॉप' नोव

25

सबसे छोटा / मैत्रीपूर्ण समाधान

की बहुत अधिक सीमाओं से निराश होने के बाद cut, मैंने अपना प्रतिस्थापन लिखा, जिसे मैंने cuts"स्टेरॉयड पर कटौती" कहा ।

कटौती प्रदान करता है क्या संभावना है कि यह और कई अन्य संबंधित कट / पेस्ट समस्याओं केलिए सबसे कम से कम समाधानहै।

एक उदाहरण, कई में से, इस विशेष प्रश्न को संबोधित करते हुए:

$ cat text.txt
0   1        2 3
0 1          2   3 4

$ cuts 2 text.txt
2
2

cuts का समर्थन करता है:

  • फाइलों में सबसे आम क्षेत्र-सीमांकक का स्वत: पता लगाना (+ डिफ़ॉल्ट को ओवरराइड करने की क्षमता)
  • मल्टी-चार, मिश्रित-चार, और रेगेक्स डेलिमिटर से मेल खाते हैं
  • मिश्रित सीमांकक के साथ कई फ़ाइलों से कॉलम निकालना
  • लाइन के अंत से ऑफसेट (नकारात्मक संख्याओं का उपयोग करना) लाइन की शुरुआत के अलावा
  • कॉलमों का स्वचालित साइड-बाय-साइड चिपकाना ( pasteअलग से आह्वान करने की आवश्यकता नहीं )
  • फ़ील्ड रीऑर्डरिंग के लिए समर्थन
  • एक कॉन्फ़िगर फ़ाइल जहां उपयोगकर्ता अपनी व्यक्तिगत वरीयताओं को बदल सकते हैं
  • उपयोगकर्ता मित्रता और न्यूनतम टाइपिंग पर बहुत जोर दिया

और भी बहुत कुछ। जिनमें से कोई भी मानक द्वारा प्रदान नहीं किया गया है cut

इसे भी देखें: https://stackoverflow.com/a/24543231/1296044

स्रोत और प्रलेखन (मुफ्त सॉफ्टवेयर): http://arielf.github.io/cuts/


4

इस पर्ल वन-लाइनर से पता चलता है कि पर्ल, aw के साथ कितनी निकटता से संबंधित है:

perl -lane 'print $F[3]' text.txt

हालाँकि, @Fऑक्सप्लिट सरणी इंडेक्स पर शुरू होती है $F[0]जबकि awk फ़ील्ड्स के साथ शुरू होती है$1


3

के संस्करणों के साथ cutमुझे पता है, नहीं, यह संभव नहीं है। cutउन फ़ाइलों को पार्स करने के लिए मुख्य रूप से उपयोगी है जहां विभाजक व्हाट्सएप (उदाहरण के लिए /etc/passwd) नहीं है और जिनके पास निश्चित संख्या में फ़ील्ड हैं। एक पंक्ति में दो विभाजक का मतलब एक खाली क्षेत्र है, और जो कि व्हाट्सएप के लिए भी जाता है।

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