2016-07-28 17 views
0

Ich brauche etwas Hilfe auf dem folgenden.Unix-Datei Zeile für Zeile lesen.Überprüfen Sie, ob eine Zeichenfolge in einer anderen Datei vorhanden ist und die erforderliche Operation ausführen

File1.txt

aaa:/path/to/aaa:777 
bob:/path/to/bbb:700 
ccc:/path/to/ccc:600 

Datei2.txt

aaa:/path/to/aaa:700 
bbb:/path/to/bbb:700 
ccc:/path/to/ccc:644 

sollte ich iterieren file2.txt und wenn aaa in File1.txt vorhanden ist, dann sollte ich die Datei Erlaubnis vergleichen. Wenn die Dateiberechtigung für aaa in beiden Dateien gleich ist, dann ignoriere sie.

Wenn sie unterschiedlich sind, dann schreiben sie in der output.txt

So in obigem Fall

Output.txt

aaa:/path/to/aaa:700 
ccc:/path/to/ccc:644 

Wie kann ich dies in Shell-Skript Unix erreichen? Bitte schlagen Sie

+1

1) Code schreiben 2) Code ausführen 3) Debug-Code. Sie sind voll verantwortlich für # 1-2, wir (vielleicht) helfen mit # 3. –

Antwort

1

vor Ich stimme dem Kommentar von @Marc zu, dass Sie etwas versuchen sollten, bevor Sie hier fragen.
Allerdings ist die folgende Antwort schwer zu finden, wenn Sie die Konstruktionen nie gesehen haben, also gebe ich Ihnen etwas zum Lernen.

Wenn Sie Zeile für Zeile analysieren möchten, können Sie mit

while IFS=: read -r file path mode; do 
    comparewith=$(grep "^${file}:${path}:" File2.txt | cut -d: -f3) 
    # compare and output 
done < File1.txt 

Für große Dateien starten, die sehr langsam sein wird. Sie können die Zeilen, die Sie vergleichen möchten, zuerst aus Datei2.txt filtern. Sie möchten grep Strings wie aaa:/path/to/aaa:, einschließlich der letzten :. Mit cut -d: -f1-2 können Sie Ihre Eingabedatei verwenden, aber vielleicht ist es besser, die letzten drei Zeichen zu entfernen: sed 's/...$//' File1.txt.
können Sie lassen grep die Ausgabe als Datei mit Ausdrücken verwenden <() mit:

grep -f <(sed 's/...$//' File1.txt) File2.txt 

Ihre Beispieldateien haben die Situation nicht zeigen, wenn beide Dateien identische Zeilen haben (die Sie überspringen möchten), müssen Sie ein anderer Prozess Substitution, dass die Arbeit zu bekommen:

grep -v -f File1.txt <(grep -f <(sed 's/...$//' File1.txt) File2.txt) 

Eine andere Lösung, selbst einen Versuch wert ist awk mit (What is "NR==FNR" in awk? für den Zugriff auf 2 Dateien sehen).

0

comm - compare two sorted files line by line

Laut Handbuch muss comm -13 <file1> <file2> nur Linien eindeutig <file2> drucken:

$ ls 
File1.txt File2.txt 
$ cat File1.txt 
aaa:/path/to/aaa:777 
bbb:/path/to/bbb:700 
ccc:/path/to/ccc:600 
$ cat File2.txt 
aaa:/path/to/aaa:700 
bbb:/path/to/bbb:700 
ccc:/path/to/ccc:644 
$ comm -13 File1.txt File2.txt 
aaa:/path/to/aaa:700 
ccc:/path/to/ccc:644 
$ # Nice! 

Aber es sucht nicht nach Zeilen in <file1>, die "ähnlich" zu entsprechenden Linien von <file2> sind. I. e. es funktioniert nicht wie Sie wollen, wenn File1.txt hat Zeile BOB:/path/to/BOB:700 und File2.txt hat BBB:/path/to/BBB:700, da es das letztere drucken wird (während Sie möchten, dass es nicht gedruckt wird).

Es wird auch nicht tun, was Sie wollen, wenn die Zeichenfolgen bbb:/path/to/bbb:700 und bbb:/another/path/to/bbb:700 "identisch" sein sollen.