2012-11-12 112 views
69

不同長度的2個未排序文本文件如何可以是由側(列)顯示側鑑於one.txttwo.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幾乎可以做到這一點,但不會對齊th e列很好,因爲它只是在列1和列2之間打印一個選項卡。我知道如何通過emacs和vim執行此操作,但希望將輸出顯示爲管道輸出的標準輸出。

我想出的解決方法是用sdiff然後用pipe sed去除輸出sdiff的增加。

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

我可以創建一個函數,堅持在我的.bashrc但肯定這個命令已經存在(或清潔解決潛在的)?

+0

不在一個外殼,但值得一提的:用[MELD](http://meldmerge.org/)! – fedorqui

回答

125

您可以使用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 
+10

完美!知道會有東西存在,以前從未聽說過「pr」。我嘗試了3個文件,輸出被截斷,但'-w'選項解決了這個問題。很好的答案。 –

+5

@sudo_o:很高興幫助,coreutils充滿了寶石 – Hasturkun

+4

偉大的-W WIDTH選項,幫助格式化它。 – 719016

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])} 
}' 

在格式規範中使用*可讓您動態提供字段長度。

+0

它的工作原理,但我不會說這是一個更清潔的解決方案: –

+1

cleaner!=更短 – Barmar

+1

從來沒有說過,但是如果我偶爾想並排顯示兩個文件,那麼執行'diff -y one.txt two.txt'比'paste one.txt two.txt'做得更好,並且刪除使用'sed'顯示的diffs額外字符與寫入/記憶awk腳本相比是微不足道的。即使在'.bash_rc'中的兩個函數更長!=更好,更易讀,更快......這裏的優點是什麼? –

2

刪除動態地從Barmar的回答字段長度計將使它更短的命令....但你仍然需要至少一個腳本來完成它不能不管你選擇什麼方法避免了工作。

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

有一個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 /; 
    " 

(當然@Hasturkun的解決方案pr最準確的!)

0
diff -y <file1> <file2> 


[root /]# cat /one.txt 
 
apple 
pear 
longer line than the last two 
last line 
[root /]# cat /two.txt 
 
The quick brown fox.. 
foo 
bar 
linux 
[[email protected] /]# diff -y one.txt two.txt 
 
apple               | The quick brown fox.. 
pear               | foo 
longer line than the last two         | bar 
last line              | linux 
+0

'sdiff'是'diff -y',我在這個問題中討論。 –

+0

是的正確的......它被提到顯示另一個命令/標誌設置。 – iAdhyan

+0

但它不回答'diff'在兩個文件之間添加字符的問題。 –

22

要擴大@Hasturkun的回答一下:在默認情況下pr只使用72爲它的輸出列,但它是相對容易使其使用終端窗口的所有可用列:

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

大多數shell的將存儲(和更新)終端的在$COLUMNS環境變量屏幕寬度,所以我們只是傳遞到pr該值用於其輸出的寬度設置。

這也回答了@Matt的問題:

是否有PR自動檢測屏幕寬度的方法嗎?

所以,沒有:pr本身無法檢測到屏幕寬度,但我們通過經-w選項,在終端的寬度傳球幫助了一點。

0

如果你想知道的兩個文件之間的實際差異使用以下命令

diff -y file1.cf file2.cf 

您還可以設置寬度打印使用-W, --width=NUM選項欄:如果知道

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

輸入文件沒有標籤,則使用expand簡化@oyssanswer

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

如果有可能是在輸入文件的製表符,你可以隨時首先展開:

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

下面爲一個基於Python的解決方案。

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