अगल-बगल दो फाइलें दिखाइए


94

अलग-अलग लंबाई की 2 बिना पढ़ी हुई पाठ फ़ाइलों को साइड में (कॉलम में) किस तरह से प्रदर्शित किया जा सकता हैshell

दिया one.txtऔर two.txt:

$ cat one.txt
apple
pear
longer line than the last two
last line

$ cat two.txt
The quick brown fox..
foo
bar 
linux

skipped a line

प्रदर्शित करें:

apple                               The quick brown fox..
pear                                foo
longer line than the last two       bar 
last line                           linux

                                    skipped a line

paste one.txt two.txtलगभग चाल करता है, लेकिन कॉलम को अच्छी तरह से संरेखित नहीं करता है क्योंकि यह कॉलम 1 और 2 के बीच एक टैब प्रिंट करता है। मुझे पता है कि यह कैसे एमएसीएस और विम के साथ है, लेकिन पाइपिंग एक्ट के लिए स्टडआउट के लिए प्रदर्शित आउटपुट चाहते हैं।

समाधान मैं उपयोग के साथ आया था sdiffऔर फिर आउटपुट को हटाने के लिए sed को पाइप करता है sdiff

sdiff one.txt two.txt | sed -r 's/[<>|]//;s/(\t){3}//'

मैं एक फ़ंक्शन बना सकता हूं और इसे अपने में चिपका सकता हूं .bashrcलेकिन निश्चित रूप से इसके लिए एक कमांड पहले से मौजूद है (या एक क्लीनर समाधान संभावित)?


शेल में नहीं, लेकिन ध्यान देने योग्य: मेल्ड का उपयोग करें !
फेडोरक्वी 'एसओ ने or

जवाबों:


166

आप ऐसा करने के prलिए उपयोग कर सकते हैं , -mध्वज का उपयोग करके फ़ाइलों को मर्ज करने के लिए, प्रति कॉलम एक, और -tहेडर को छोड़ने के लिए, उदाहरण के लिए।

pr -m -t one.txt two.txt

आउटपुट:

apple                               The quick brown fox..
pear                                foo
longer line than the last two       bar
last line                           linux

                                    skipped a line

यह सभी देखें:


15
उत्तम! कुछ पता था, prपहले कभी नहीं सुना होगा । मैंने 3 फाइलों के साथ कोशिश की और आउटपुट को छोटा कर दिया गया लेकिन -wविकल्प ने हल कर दिया। अच्छा उत्तर।
क्रिस सेमोर

5
@sudo_o: मदद करने के लिए खुश, कोरुटिल जवाहरात से भरा है
Coreutils

1
वहाँ एक तरीका है ऑटो स्क्रीन का पता लगाने के लिए जनसंपर्क?
मैट

2
@ मैट: आप उपयोग कर सकते हैं $COLUMNS, जिसे शेल द्वारा प्रदान किया जाना चाहिए।
हस्त्कुर्कन

1
जब दो फ़ाइलों को एक साथ प्रिंट करने के लिए उपयोग किया जाता है, तो prलंबी लाइनों के अंत में कटौती होती है। वहाँ एक तरह से यह लाइनों को लपेटने के लिए है?
मोलनरग

32

@Hasturkun के उत्तर पर थोड़ा विस्तार करने के लिए : डिफ़ॉल्ट रूप से prइसके उत्पादन के लिए केवल 72 स्तंभों का उपयोग करता है, लेकिन इसे अपने टर्मिनल विंडो के सभी उपलब्ध स्तंभों का उपयोग करना अपेक्षाकृत आसान है:

pr -w $COLUMNS -m -t one.txt two.txt

अधिकांश शेल का पर्यावरण चर में आपके टर्मिनल की स्क्रीन की उपलब्धता को स्टोर करेगा (और अपडेट करेगा)$COLUMNS , इसलिए हम prइसके आउटपुट की चौड़ाई सेटिंग के लिए उपयोग करने के लिए उस मान को पास कर रहे हैं ।

यह भी @Matt के सवाल का जवाब देता है :

वहाँ एक तरीका है ऑटो स्क्रीन का पता लगाने के लिए जनसंपर्क?

तो, नहीं: prस्वयं स्क्रीन का पता नहीं लगा सकता है, लेकिन हम -wविकल्प के माध्यम से टर्मिनल की चौड़ाई में पास करके थोड़ी मदद कर रहे हैं ।


7

यदि आप जानते हैं कि इनपुट फ़ाइलों में कोई टैब नहीं है, तो @oys के उत्तर कोexpand सरल बनाते हुए :

paste one.txt two.txt | expand --tabs=50

यदि इनपुट फ़ाइलों में टैब हो सकते हैं, तो आप हमेशा पहले का विस्तार कर सकते हैं:

paste <(expand one.txt) <(expand two.txt) | expand --tabs=50

6
paste one.txt two.txt | awk -F'\t' '{
    if (length($1)>max1) {max1=length($1)};
    col1[NR] = $1; col2[NR] = $2 }
    END {for (i = 1; i<=NR; i++) {printf ("%-*s     %s\n", max1, col1[i], col2[i])}
}'

*एक प्रारूप विनिर्देश में उपयोग करने से आप क्षेत्र की लंबाई को गतिशील रूप से आपूर्ति कर सकते हैं।


1
कभी नहीं कहा कि यह किया है, लेकिन अगर मैं कभी-कभी दो फ़ाइलों को एक साथ प्रदर्शित करना चाहता हूं, तो diff -y one.txt two.txtएक बेहतर काम करता है paste one.txt two.txtऔर अलग-अलग वर्णों को हटाने से अलग होता sedहै जो एक awkस्क्रिप्ट को लिखने / याद रखने के साथ तुलनात्मक रूप से तुच्छ होते हैं । यहां तक ​​कि .bash_rcलंबे समय तक दोनों कार्यों के साथ ! = बेहतर, अधिक पठनीय, तेज .. यहां क्या फायदा है?
क्रिस सेमोर

2

बारमर के उत्तर से गतिशील रूप से क्षेत्र की लंबाई की गिनती को हटा दें, यह एक बहुत छोटी कमांड बना देगा .... लेकिन आपको अभी भी काम खत्म करने के लिए कम से कम एक स्क्रिप्ट की आवश्यकता है जिसे आप जिस भी तरीके से चुनते हैं, उससे बचा नहीं जा सकता है।

paste one.txt two.txt |awk -F'\t' '{printf("%-50s %s\n",$1,$2)}'

2

यदि आप दो फ़ाइलों के बीच वास्तविक अंतर को जानना चाहते हैं, तो उपयोग करें diff -y:

diff -y file1.cf file2.cf

आप -W, --width=NUMविकल्प का उपयोग करके आउटपुट चौड़ाई भी सेट कर सकते हैं :

diff -y -W 150 file1.cf file2.cf

और diffस्तंभ के आउटपुट को आपकी वर्तमान टर्मिनल विंडो में फिट करने के लिए :

diff -y -W $COLUMNS file1.cf file2.cf

2

एक sedतरीका है:

f1width=$(wc -L <one.txt)
f1blank="$(printf "%${f1width}s" "")"
paste one.txt two.txt |
    sed "
        s/^\(.*\)\t/\1$f1blank\t/;
        s/^\(.\{$f1width\}\) *\t/\1 /;
    "

के अंतर्गत , आप उपयोग कर सकते हैं printf -v:

f1width=$(wc -L <one.txt)
printf -v f1blank "%${f1width}s"
paste one.txt two.txt |
    sed "s/^\(.*\)\t/\1$f1blank\t/;
         s/^\(.\{$f1width\}\) *\t/\1 /;"

(बेशक @Hasturkun के समाधान का prहै सबसे सटीक !) :

का लाभ sedअधिकpr

आप बारीक से अलग चौड़ाई और या विभाजक चुन सकते हैं:

f1width=$(wc -L <one.txt)
(( f1width += 4 ))         # Adding 4 spaces
printf -v f1blank "%${f1width}s"
paste one.txt two.txt |
    sed "s/^\(.*\)\t/\1$f1blank\t/;
         s/^\(.\{$f1width\}\) *\t/\1 /;"

या, नमूने के लिए, जिसमें रेखाएँ हों line:

f1width=$(wc -L <one.txt)
printf -v f1blank "%${f1width}s"
paste one.txt two.txt |
    sed "s/^\(.*\)\t/\1$f1blank\t/;
  /line/{s/^\(.\{$f1width\}\) *\t/\1 |ln| /;ba};
         s/^\(.\{$f1width\}\) *\t/\1 |  | /;:a"

प्रस्तुत करना होगा:

apple                         |  | The quick brown fox..
pear                          |  | foo
longer line than the last two |ln| bar 
last line                     |ln| linux
                              |  | 
                              |ln| skipped a line

1

एक अजगर आधारित समाधान के नीचे खोजें।

import sys

# Specify the number of spaces between the columns
S = 4

# Read the first file
l0 = open( sys.argv[1] ).read().split('\n')

# Read the second file
l1 = open( sys.argv[2] ).read().split('\n')

# Find the length of the longest line of the first file
n = len(max(l0, key=len))

# Print the lines
for i in  xrange( max( len(l0), len(l1) ) ):

    try:
        print l0[i] + ' '*( n - len(l0[i]) + S) + l1[i]
    except:
        try:
            print ' ' + ' '*( n - 1 + S) + l1[i]
        except:
            print l0[i]

उदाहरण

apple                            The quick brown fox..
pear                             foo
longer line than the last two    bar 
last line                        linux

                                 skipped a line

0
diff -y <file1> <file2>


[root /]# cat /one.txt
सेब
नाशपाती
पिछले दो की तुलना में लंबी लाइन
अंतिम पंक्ति
[root /]# cat /two.txt
द क्विक ब्राउन फ़ॉक्स..
foo
बार
linux
[root@RHEL6-64 /]# diff -y one.txt two.txt
सेब | द क्विक ब्राउन फ़ॉक्स..
नाशपाती | foo
पिछले दो की तुलना में लंबी लाइन | बार
अंतिम पंक्ति | linux

sdiffहै diff -yजो मैं प्रश्न में चर्चा की।
क्रिस सेमुर

हाँ ठीक है ... यह करने के लिए एक और कमांड / ध्वज सेटिंग दिखाने का उल्लेख किया गया था।
आई। जहान

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