जवाबों:
के लिए cut(1)
आदमी पेज:
एक का उपयोग करें, और केवल -b, -c या -f में से एक का उपयोग करें। प्रत्येक LIST एक सीमा से बना होता है, या कई श्रेणी अल्पविराम द्वारा अलग होती हैं। चयनित इनपुट उसी क्रम में लिखा जाता है जिसे वह पढ़ा जाता है, और ठीक एक बार लिखा जाता है।
यह पहले फ़ील्ड 1 पर पहुँचता है, इसलिए यह प्रिंट होता है, इसके बाद फ़ील्ड 2 आता है।
awk
इसके बजाय उपयोग करें :
awk '{ print $2 " " $1}' file.txt
FS
एक विकल्प है, OFS
एक चर है। जैसेawk -v OFS=";" -F"\t" '{print $2,$1}'
| sed 's/\r//' |
पहले इसे पाइप सेawk
awk '{print $4 "\t" $2 "\t" $6 "\t" $7}' file
आप भी जोड़ सकते हैं cut
और paste
:
paste <(cut -f2 file.txt) <(cut -f1 file.txt)
टिप्पणियों के माध्यम से: यह संभव है कि मार से बचने के लिए और कट की एक आवृत्ति को हटा दें:
paste file.txt file.txt | cut -f2,3
cut
जब तक आपके पास एक अद्वितीय स्तंभ विभाजक है, तब तक चर-लंबाई वाले स्तंभों के लिए ठीक काम करता है।
bash
वाद और का एक उदाहरण को दूर cut
: करके paste file.txt file.txt | cut -f2,3
सिर्फ शेल का उपयोग करके,
while read -r col1 col2
do
echo $col2 $col1
done <"file"
"$col2"
और "$col1"
डेटा में शेल मेटाचैकर या अन्य शेंनिगन हो सकते हैं।
आप उसके लिए पर्ल का उपयोग कर सकते हैं:
perl -ane 'print "$F[1] $F[0]\n"' < file.txt
पर्ल को चलाने का लाभ यह है कि (यदि आप पर्ल को जानते हैं) तो आप रीयररेंजिंग कॉलम की तुलना में एफ पर बहुत अधिक गणना कर सकते हैं।
perl -ae print
काम करता हैcat
का उपयोग कर join
:
join -t $'\t' -o 1.2,1.1 file.txt file.txt
टिप्पणियाँ:
-t $'\t'
में जीएनयू join
अधिक सहज ज्ञान युक्त -t '\t'
बिना$
विफल रहता है, ( coreutils v8.28 और पहले?); यह शायद एक बग है कि वर्कअराउंड की तरह $
आवश्यक होना चाहिए। देखें: यूनिक्स विभाजक चार में शामिल होने के ।
join
दो फ़ाइलनामों की आवश्यकता है, भले ही वहाँ केवल एक फ़ाइल पर काम किया जा रहा हो। join
वांछित क्रिया करने में दो बार समान नाम का उपयोग करना ।
कम संसाधनों वाली प्रणालियों के लिए join
अन्य उत्तरों में प्रयुक्त कुछ उपकरणों की तुलना में एक छोटा पदचिह्न प्रदान करता है:
wc -c $(realpath `which cut join sed awk perl`) | head -n -1
43224 /usr/bin/cut
47320 /usr/bin/join
109840 /bin/sed
658072 /usr/bin/gawk
2093624 /usr/bin/perl
बस कुछ इसी तरह काम कर रहा हूं, मैं एक विशेषज्ञ नहीं हूं, लेकिन मुझे लगा कि मैं उन कमांडों को साझा करूंगा जिनका मैंने उपयोग किया है। मेरे पास एक मल्टी कॉलम सीएसवी था जिसमें मुझे केवल 4 कॉलमों की आवश्यकता थी और फिर मुझे उन्हें पुनः व्यवस्थित करने की आवश्यकता थी।
मेरी फ़ाइल 'पाइप थी।' सीमांकित लेकिन वह अदला-बदली की जा सकती है।
LC_ALL=C cut -d$'|' -f1,2,3,8,10 ./file/location.txt | sed -E "s/(.*)\|(.*)\|(.*)\|(.*)\|(.*)/\3\|\5\|\1\|\2\|\4/" > ./newcsv.csv
माना जाता है कि यह वास्तव में खुरदरा और तैयार है लेकिन इसे सूट किया जा सकता है!
Sed का उपयोग करना
स्तंभ सामग्री को कैप्चर करने और पुन: व्यवस्थित करने के लिए मूल नियमित अभिव्यक्ति के नेस्टेड सबएक्सप्रेस के साथ sed का उपयोग करें। जब इस मामले में पुन: स्तंभों की सीमित संख्या में कटौती होती है, तो यह दृष्टिकोण सबसे उपयुक्त होता है।
मूल विचार खोज पैटर्न के दिलचस्प अंशों को घेरना है \(
और \)
, जिन्हें प्रतिस्थापन पैटर्न में वापस खेला जा सकता है, \#
जहां #
खोज पैटर्न में उपसंचाई की अनुक्रमिक स्थिति का प्रतिनिधित्व करता है।
उदाहरण के लिए:
$ echo "foo bar" | sed "s/\(foo\) \(bar\)/\2 \1/"
पैदावार:
bar foo
सब-डेफ़िसिएशन के बाहर का पाठ स्कैन किया गया है लेकिन प्रतिस्थापन स्ट्रिंग में प्लेबैक के लिए इसे बरकरार नहीं रखा गया है।
यद्यपि प्रश्न में निश्चित चौड़ाई के स्तंभों पर चर्चा नहीं की गई है, हम यहां चर्चा करेंगे क्योंकि यह किसी भी समाधान के योग्य उपाय है। सरलता के लिए मान लेते हैं कि फ़ाइल स्पेस सीमांकित है, हालांकि समाधान को अन्य सीमांकक के लिए बढ़ाया जा सकता है।
Collapsing Spaces
सरलतम उपयोग को स्पष्ट करने के लिए, मान लेते हैं कि कई स्थानों को एकल स्थानों में ढहाया जा सकता है, और दूसरे स्तंभ मानों को ईओएल के साथ समाप्त किया जाता है (और अंतरिक्ष में गद्देदार नहीं)।
फ़ाइल:
bash-3.2$ cat f
Column1 Column2
str1 1
str2 2
str3 3
bash-3.2$ od -a f
0000000 C o l u m n 1 sp sp sp sp C o l u m
0000020 n 2 nl s t r 1 sp sp sp sp sp sp sp 1 nl
0000040 s t r 2 sp sp sp sp sp sp sp 2 nl s t r
0000060 3 sp sp sp sp sp sp sp 3 nl
0000072
रूपांतरण करें:
bash-3.2$ sed "s/\([^ ]*\)[ ]*\([^ ]*\)[ ]*/\2 \1/" f
Column2 Column1
1 str1
2 str2
3 str3
bash-3.2$ sed "s/\([^ ]*\)[ ]*\([^ ]*\)[ ]*/\2 \1/" f | od -a
0000000 C o l u m n 2 sp C o l u m n 1 nl
0000020 1 sp s t r 1 nl 2 sp s t r 2 nl 3 sp
0000040 s t r 3 nl
0000045
कॉलम चौड़ाई का संरक्षण
आइए अब किसी फ़ाइल को विधि को निरंतर चौड़ाई वाले स्तंभों के साथ बढ़ाते हैं, जबकि स्तंभों को अलग-अलग चौड़ाई वाले होते हैं।
फ़ाइल:
bash-3.2$ cat f2
Column1 Column2
str1 1
str2 2
str3 3
bash-3.2$ od -a f2
0000000 C o l u m n 1 sp sp sp sp C o l u m
0000020 n 2 nl s t r 1 sp sp sp sp sp sp sp 1 sp
0000040 sp sp sp sp sp nl s t r 2 sp sp sp sp sp sp
0000060 sp 2 sp sp sp sp sp sp nl s t r 3 sp sp sp
0000100 sp sp sp sp 3 sp sp sp sp sp sp nl
0000114
रूपांतरण करें:
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f2
Column2 Column1
1 str1
2 str2
3 str3
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f2 | od -a
0000000 C o l u m n 2 sp C o l u m n 1 sp
0000020 sp sp nl 1 sp sp sp sp sp sp sp s t r 1 sp
0000040 sp sp sp sp sp nl 2 sp sp sp sp sp sp sp s t
0000060 r 2 sp sp sp sp sp sp nl 3 sp sp sp sp sp sp
0000100 sp s t r 3 sp sp sp sp sp sp nl
0000114
अंत में, हालांकि प्रश्न के उदाहरण में असमान लंबाई के तार नहीं हैं, यह सेड अभिव्यक्ति इस मामले का समर्थन करती है।
फ़ाइल:
bash-3.2$ cat f3
Column1 Column2
str1 1
string2 2
str3 3
रूपांतरण करें:
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f3
Column2 Column1
1 str1
2 string2
3 str3
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f3 | od -a
0000000 C o l u m n 2 sp C o l u m n 1 sp
0000020 sp sp nl 1 sp sp sp sp sp sp sp s t r 1 sp
0000040 sp sp sp sp sp nl 2 sp sp sp sp sp sp sp s t
0000060 r i n g 2 sp sp sp nl 3 sp sp sp sp sp sp
0000100 sp s t r 3 sp sp sp sp sp sp nl
0000114
खोल के नीचे स्तंभ के अन्य तरीकों की तुलना
एक फ़ाइल हेरफेर उपकरण के लिए आश्चर्यजनक रूप से, awk एक क्षेत्र से रिकॉर्ड के अंत तक काटने के लिए अच्छी तरह से अनुकूल नहीं है। Sed में यह नियमित अभिव्यक्तियों का उपयोग करके पूरा किया जा सकता है, उदाहरण के लिए स्तंभ से मेल खाने के लिए अभिव्यक्ति \(xxx.*$\)
कहाँ xxx
है।
शेल स्क्रिप्ट्स को लागू करते समय पेस्ट और कट सबस्क्रिप्शन का उपयोग करना मुश्किल हो जाता है। कमांड से काम करने वाला कोड शेल स्क्रिप्ट के अंदर लाए जाने पर पार्स करने में विफल रहता है। कम से कम यह मेरा अनुभव था (जो मुझे इस दृष्टिकोण तक ले गया)।
@Met से उत्तर पर विस्तार करते हुए, पर्ल का उपयोग करते हुए भी:
यदि इनपुट और आउटपुट TAB- सीमांकित हैं:
perl -F'\t' -lane 'print join "\t", @F[1, 0]' in_file
यदि इनपुट और आउटपुट व्हाट्सएप-सीमांकित हैं:
perl -lane 'print join " ", @F[1, 0]' in_file
यहाँ,
-e
पर्ल को एक अलग स्क्रिप्ट फ़ाइल के बजाय कोड इनलाइन देखने के लिए कहता है ,
-n
एक बार में इनपुट 1 लाइन पढ़ता है , लाइन पढ़ने के बाद
-l
इनपुट रिकॉर्ड विभाजक ( \n
* NIX) को हटाता है (समान chomp
), और आउटपुट जोड़ें रिकॉर्ड विभाजक ( \n
प्रत्येक के लिए * NIX पर) print
,
-a
सरणी में खाली स्थान के पर इनपुट लाइन विभाजन @F
,
-F'\t'
संयोजन में साथ -a
विभाजन टैब पर इनपुट लाइन, खाली स्थान के के बजाय सरणी में@F
।
@F[1, 0]
@F
इस क्रम में सरणी के 2 और 1 तत्वों से बना सरणी है । याद रखें कि पर्ल में सरणियाँ शून्य-अनुक्रमित हैं, जबकि फ़ील्ड cut
1-अनुक्रमित हैं। तो फ़ील्ड्स @F[0, 1]
उसी फ़ील्ड के समान हैं, जिसमें वाले फ़ील्ड हैंcut -f1,2
।
ध्यान दें कि इस तरह के संकेतन ऊपर पोस्ट किए गए कुछ अन्य उत्तरों की तुलना में इनपुट के अधिक लचीले हेरफेर को सक्षम बनाता है (जो एक साधारण कार्य के लिए ठीक हैं)। उदाहरण के लिए:
# reverses the order of fields:
perl -F'\t' -lane 'print join "\t", reverse @F' in_file
# prints last and first fields only:
perl -F'\t' -lane 'print join "\t", @F[-1, 0]' in_file
cut
है यह सहज ज्ञान युक्त री-ऑर्डरिंग आदेश का समर्थन नहीं करता है। वैसे भी, एक और टिप: आप उपयोग कर सकतेawk
है-FS
और-OFS
विकल्प के लिए उपयोग कस्टम इनपुट और आउटपुट क्षेत्र विभाजक (जैसे-d
और--output-delimiter
के लिएcut
)।