एक अन्य मल्टी कॉलम टेक्स्ट फाइल पाने के लिए एक मल्टी कॉलम टेक्स्ट फाइल को कैसे प्रोसेस करें?


17

मेरे पास एक टेक्स्ट फाइल है:

a   aa  aaa     b   bb  bbb     c   cc  ccc
d   dd  ddd     e   ee  eee     f   ff  fff
g   gg  ggg     h   hh  hhh     i   ii  iii
j   jj  jjj

मैं इसे कैसे संसाधित कर सकता हूं और इस तरह 2 कॉलम फाइल प्राप्त कर सकता हूं:

a   aa
aaa b
bb  bbb
c   cc
ccc d
dd  ddd
e   ee
eee f
ff  fff
g   gg
ggg h
hh  hhh
i   ii
iii j
jj  jjj

या इस तरह एक तीन कॉलम फ़ाइल:

a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jj

मैं अजीब समाधान प्राप्त करना पसंद करता हूं लेकिन अन्य समाधानों का भी स्वागत किया जाता है।

जवाबों:


1

आप इसे GNU awk के एकल आह्वान के साथ भी कर सकते हैं:

reshape.awk

# Set awk to split input at whitespace characters and
# use tab as the output field separator 
BEGIN {
  RS="[ \t\n]+"
  OFS="\t"
}

# Print using OFS or ORS based on the element index
{
  printf "%s", $1 (NR%n == 0 ? ORS : OFS)
}

# Append a missing new-line when last row is not full
END { 
  if( NR%n != 0) 
    printf "\n"
}

इसे इस तरह चलाएं:

awk -f reshape.awk n=2 infile

या वन-लाइनर के रूप में:

awk -v n=2 'BEGIN { RS="[ \t\n]+"; OFS="\t" } { printf "%s", $1 (NR%n == 0 ? ORS : OFS) } END { if( NR%n != 0) printf "\n" }' infile

आउटपुट:

a   aa
aaa b
bb  bbb
c   cc
ccc d
dd  ddd
e   ee
eee f
ff  fff
g   gg
ggg h
hh  hhh
i   ii
iii j
jj  jjj

या साथ n=3:

a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj

क्या यह प्रारूप स्ट्रिंग के $1रूप में उपयोग नहीं करता है ? printf
वाइल्डकार्ड 16

@Wildcard: सही है, यह उपयोग करने के लिए सुरक्षित है "%s", ...। अपडेट
थोर

पुष्टि करने के लिए धन्यवाद। :) वही awkआपके अन्य प्रश्न के उत्तर में कमांड पर लागू होता है, वैसे।
वाइल्डकार्ड

20

प्रत्येक फ़ील्ड को एक पंक्ति और पोस्ट-स्तंभ पर रखें।

एक लाइन पर प्रत्येक क्षेत्र

टीआर

tr -s ' ' '\n' < infile

ग्रेप

grep -o '[[:alnum:]]*' infile

sed

sed 's/\s\+/\n/g' infile

या अधिक पोर्टेबल:

sed 's/\s\+/\
/g' infile

awk

awk '$1=$1' OFS='\n' infile

या

awk -v OFS='\n' '$1=$1' infile

Columnate

पेस्ट

2 कॉलम के लिए:

... | paste - -

3 कॉलम के लिए:

... | paste - - -

आदि।

sed

2 कॉलम के लिए:

... | sed 'N; s/\n/\t/g'

3 कॉलम के लिए:

... | sed 'N; N; s/\n/\t/g'

आदि।

xargs

... | xargs -n number-of-desired-columns

जैसा कि प्रिंट करने के लिए xargsउपयोग किया /bin/echoजाता है, उस डेटा से सावधान रहें जो विकल्प की तरह दिखता है, जैसे कि echoव्याख्या की जाएगी।

awk

... | awk '{ printf "%s", $0 (NR%n==0?ORS:OFS) }' n=number-of-desired-columns OFS='\t'

जनसंपर्क

... | pr -at -number-of-desired-columns

या

... | pr -at -s$'\t' -number-of-desired-columns

कॉलम (ऑटोजेन पैकेज से)

... | columns -c number-of-desired-columns

विशिष्ट उत्पादन:

a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj

2
जोरदार तरीके से डुबोना। +1 सर
स्टीवन पेनी

xargsलाइन कॉल नहीं होना चाहिए echoया printf?
वाइल्डकार्ड

1
@Wildcard: डिफ़ॉल्ट रूप से xargsकॉल/bin/echo
थोर

1
वाह, मुझे पता नहीं था! यह POSIX द्वारा भी निर्दिष्ट है । धन्यवाद!
वाइल्डकार्ड

@Wildcard: डेटा भेजना समस्याओं के कारणों के xargsविकल्प की तरह दिखता /bin/echoहै ... मैंने एक चेतावनी जोड़ी।
थोर

9
$ sed -E 's/\s+/\n/g' ip.txt | paste - -
a   aa
aaa b
bb  bbb
c   cc
ccc d
dd  ddd
e   ee
eee f
ff  fff
g   gg
ggg h
hh  hhh
i   ii
iii j
jj  jjj

$ sed -E 's/\s+/\n/g' ip.txt | paste - - -
a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj

9

जैसा कि वाइल्डकार्ड ने बताया, यह केवल तभी काम करेगा जब आपकी फ़ाइल अच्छी तरह से स्वरूपित हो, इसमें कोई विशेष वर्ण नहीं हैं जो शेल ग्लब्स के रूप में व्याख्या करेगा और आप डिफ़ॉल्ट शब्द विभाजन नियमों से खुश हैं। यदि इस बारे में कोई सवाल है कि क्या आपकी फ़ाइलें उस परीक्षा को "पास" करेंगी, तो इस दृष्टिकोण का उपयोग न करें।

एक संभावना यह करने के लिए उपयोग printfकरने के लिए किया जाएगा

printf '%s\t%s\n' $(cat your_file)

यह सामग्री की विभाजन पर शब्द विभाजन your_fileकरेगा और उन्हें जोड़ देगा और बीच-बीच में उन्हें टैब के साथ प्रिंट कर सकता है। अतिरिक्त कॉलम रखने %sके printfलिए आप अधिक प्रारूप स्ट्रिंग्स का उपयोग कर सकते हैं।


1
फ़ाइल पर निर्भर करता है जिसमें कोई विशेष वर्ण नहीं है। यदि यह है, उदाहरण के लिए, किसी भी तारांकन (*) आप बहुत अप्रत्याशित परिणाम मिल जाएगा।
वाइल्डकार्ड

4
perl -n0E 'say s/\s+/ ++$n % 4 ?"\t":"\n"/gre' file

(कॉलम की संख्या से 4 बदलें)


4

बीएसडी rs(रिशेप) उपयोगिता:

$ rs 0 2
a   aa  aaa     b   bb  bbb     c   cc  ccc
d   dd  ddd     e   ee  eee     f   ff  fff
g   gg  ggg     h   hh  hhh     i   ii  iii
j   jj  jjj
[Ctrl-D][Enter]
a    aa
aaa  b
bb   bbb
c    cc
ccc  d
dd   ddd
e    ee
eee  f
ff   fff
g    gg
ggg  h
hh   hhh
i    ii
iii  j
jj   jjj

0 2है पंक्तियों और स्तंभों । निर्दिष्ट करने का 0अर्थ है "स्तंभों से पंक्तियों की स्वचालित रूप से गणना करें"।


3

पायथन लिपि दृष्टिकोण।

यहां मूल विचार आपके पाठ के सभी शब्दों को एक सूची में समतल करना है, और फिर प्रत्येक दूसरे आइटम के बाद नई-पंक्ति प्रिंट करना है (जो कि दो कॉलम में कॉलम करने के लिए है)। यदि आप 3 कॉलम चाहते हैं, तो बदल index%2देंindex%3

#!/usr/bin/env python3
import sys

items = [i for l in sys.stdin 
           for i in l.strip().split()]
line = []
for index,item in enumerate(items,1):
    line.append(item)
    if index%2 == 0:
       print("\t".join(line))
       line = []

नमूना उत्पादन:

$ python recolumnate.py < input.txt                                            
a   aa
aaa b
bb  bbb
c   cc
ccc d
dd  ddd
e   ee
eee f
ff  fff
g   gg
ggg h
hh  hhh
i   ii
iii j
jj  jjj

तीन-स्तंभ संस्करण (जैसा कि ऊपर कहा गया है, केवल index%3 == 0परिवर्तित)

$ cat recolumnate.py                                                           
#!/usr/bin/env python3
import sys

items = [i for l in sys.stdin 
           for i in l.strip().split()]
line = []
for index,item in enumerate(items,1):
    line.append(item)
    if index%3 == 0:
       print("\t".join(line))
       line = []

$ python recolumnate.py < input.txt                                            
a   aa  aaa
b   bb  bbb
c   cc  ccc
d   dd  ddd
e   ee  eee
f   ff  fff
g   gg  ggg
h   hh  hhh
i   ii  iii
j   jj  jjj
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.