Wie können 2 unsortierte Textdateien unterschiedlicher Länge nebeneinander angezeigt werden (in Spalten) in einem Shell
name__
Angegebener one.txt
und 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
Anzeige:
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
macht fast den Trick, richtet die Spalten aber nicht richtig aus, da nur ein Tab zwischen Spalte 1 und 2 gedruckt wird. Ich weiß, wie das mit Emacs und Vim geht, möchte aber, dass die Ausgabe für Piping ect stdout angezeigt wird.
Die Lösung, die ich gefunden habe, verwendet sdiff
und leitet dann an sed weiter, um die Ausgabe zu entfernen, die sdiff
hinzufügt.
sdiff one.txt two.txt | sed -r 's/[<>|]//;s/(\t){3}//'
Ich könnte eine Funktion erstellen und sie in meinen .bashrc
einfügen, aber es gibt sicherlich bereits einen Befehl dafür (oder möglicherweise eine BereinigungsLösung).
Sie können dazu pr
verwenden. Verwenden Sie das Flag -m
, um die Dateien zusammenzuführen (eine pro Spalte) und -t
, um Kopfzeilen wegzulassen.
pr -m -t one.txt two.txt
ausgänge:
Apple The quick brown fox..
pear foo
longer line than the last two bar
last line linux
skipped a line
Um die Antwort von @Hasturkun ein wenig zu erweitern: Standardmäßig verwendet pr
nur 72 Spalten für die Ausgabe, aber es ist relativ einfach, alle verfügbaren Spalten Ihres Terminalfensters zu verwenden:
pr -w $COLUMNS -m -t one.txt two.txt
Die meisten Shells speichern (und aktualisieren) die Bildschirmbreite Ihres Terminals in der Umgebungsvariable $COLUMNS
. Daher übergeben wir diesen Wert nur an pr
, um die Breiteneinstellung der Ausgabe zu verwenden.
Dies beantwortet auch die Frage von @Matt :
Gibt es eine Möglichkeit für pr, die Bildschirmbreite automatisch zu erkennen?
No: pr
selbst kann die Bildschirmbreite nicht erkennen, aber wir helfen ein wenig, indem wir die Breite des Terminals über die -w
-Option übergeben.
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])}
}'
Durch die Verwendung von *
in einer Formatspezifikation können Sie die Feldlänge dynamisch angeben.
Wenn Sie wissen, dass die Eingabedateien keine Tabulatoren haben, vereinfacht die Verwendung von expand
@oyss 's answer :
paste one.txt two.txt | expand --tabs=50
Wenn sich in den Eingabedateien Registerkarten befinden könnten, können Sie immer zuerst erweitern:
paste <(expand one.txt) <(expand two.txt) | expand --tabs=50
wenn Sie die Zählung der Feldlänge dynamisch aus der Antwort von Barmar entfernen, wird der Befehl viel kürzer. Sie benötigen jedoch mindestens ein Skript, um die Arbeit abzuschließen, die unabhängig von der gewählten Methode nicht vermieden werden kann.
paste one.txt two.txt |awk -F'\t' '{printf("%-50s %s\n",$1,$2)}'
Es gibt einen sed
Weg:
f1width=$(wc -L <one.txt)
f1blank="$(printf "%${f1width}s" "")"
paste one.txt two.txt |
sed "
s/^\(.*\)\t/\1$f1blank\t/;
s/^\(.\{$f1width\}\) *\t/\1 /;
"
(Natürlich ist die Lösung von @Hasturkun pr
die genaueste !):
Wenn Sie den tatsächlichen Unterschied zwischen zwei Dateien nebeneinander ermitteln möchten, verwenden Sie diff -y
:
diff -y file1.cf file2.cf
Sie können auch eine Ausgabebreite mit der Option -W, --width=NUM
einstellen:
diff -y -W 150 file1.cf file2.cf
und um die Spaltenausgabe von diff
an Ihr aktuelles Terminalfenster anzupassen:
diff -y -W $COLUMNS file1.cf file2.cf
Nachfolgend finden Sie eine auf Python basierende Lösung.
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]
Beispiel
Apple The quick brown fox..
pear foo
longer line than the last two bar
last line linux
skipped a line
diff -y <file1> <file2>
[root /]# cat /one.txt
Apple Pear Längere Zeile als die letzten beiden Letzte Zeile
[root /]# cat /two.txt
Der schnelle braune Fuchs .. Foo Bar Linux
[[email protected] /]# diff -y one.txt two.txt
Apple | Der schnelle braune Fuchs .. Birne | foo längere Zeile als die letzten beiden | bar letzte Zeile | Linux