Celem skryptu, który tworzę, jest porównanie dwóch serii plików. Nazwy plików są przechowywane w dwóch osobnych plikach, po jednej ścieżce na wiersz. Moim pomysłem jest posiadanie dwóch while read
pętli, po jednej dla każdej listy nazw plików, ale jak mogę mieszać obie pętle razem?
while read compareFile <&3; do
if [[ ! $server =~ [^[:space:]] ]] ; then #empty line exception
continue
fi
echo "Comparing file - $compareFile"
if diff "$compareFile" _(other file from loop?_) >/dev/null ; then
echo Same
else
echo Different
fi
done 3</infanass/dev/admin/filestoCompare.txt
Muszę być w stanie porównywać pliki z dwóch różnych list jednocześnie przez dwa podczas odczytu pętli ... Czy to w ogóle możliwe?
bash
shell-script
control-flow
mkrouse
źródło
źródło
diff
.diff
.Odpowiedzi:
Nie potrzebujesz dwóch pętli; wystarczy odczytać z dwóch plików w jednej pętli.
źródło
Metoda 1: użyj tego, co wiesz
Ponieważ wiesz już, jak zapętlić jeden plik, możesz połączyć pliki, a następnie przetworzyć połączone pliki. Polecenie
paste
łączy dwa pliki linia po linii. Umieszcza tabulator między wierszami pochodzącymi z dwóch plików, więc to rozwiązanie zakłada, że w nazwach plików nie ma tabulatorów. (Możesz zmienić separator, ale musisz znaleźć znak, którego nie ma w nazwie pliku).Jeśli chcesz pominąć puste linie, musisz to zrobić w każdym pliku osobno, ponieważ
paste
może on pasować do pustej linii z jednego pliku z niepustą linią z innego pliku. Możesz użyćgrep
do filtrowania niepustych linii.Pamiętaj, że jeśli dwa pliki mają różne długości, otrzymasz pusty
$file2
(niezależnie od tego, która lista kończy się jako pierwsza).Metoda 2: zapętlenie dwóch plików
Możesz umieścić tak złożone polecenie, jak chcesz w warstwie pętli while. Jeśli wstawisz,
read file1 <&3 && read file2 <&4
pętla będzie działać tak długo, jak oba pliki będą miały linię do odczytania, tj. Dopóki jeden plik się nie skończy.Jeśli chcesz pominąć puste linie, jest to trochę bardziej skomplikowane, ponieważ musisz wykonać pomijanie dwóch plików niezależnie. Prostym sposobem jest podzielenie problemu na dwie części: pominięcie pustych linii z jednego pliku i przetworzenie niepustych linii. Jedną z metod pomijania pustych linii jest przetworzenie
grep
jak wyżej. Uważaj na niezbędną przestrzeń między<
operatorem przekierowania a operatorem<(
rozpoczynającym zawieszanie polecenia.Inną metodą jest napisanie funkcji, która zachowuje się tak,
read
ale pomija puste linie. Ta funkcja może działać, wywołującread
pętlę. Nie musi to być funkcja, ale funkcja jest najlepszym podejściem, zarówno do uporządkowania kodu, jak i dlatego, że ten fragment kodu należy wywołać dwukrotnie. W funkcji${!#}
jest instancja konstrukcji bash,${!VARIABLE}
która ocenia wartość zmiennej, której nazwa jest wartościąVARIABLE
; tutaj zmienna jest specjalną zmienną,#
która zawiera liczbę parametru pozycyjnego, podobnie${!#}
jak ostatni parametr pozycyjny.źródło
-u
opcji odczytuJednym z podejść byłoby użycie
read -ra
zamiast sprawiedliwegoread
. Zakładając, żefilestoCompare.txt
zawarte 2 kolumny z nazwami plików w każdy, możeread -ra
byłoby przeczytać obie kolumny w tym samym czasie i przypisać je do tablicy,compareFile
. Następnie można uzyskać dostęp do tej tablicy, aby indeks 0 był pierwszym plikiem, a indeks 1 drugim plikiem za każdym razem przezwhile
pętlę.Przykład
Powiedz, że mam ten plik:
filestoCompare.txt
i zawiera on:Polecenie przejścia przez ten plik będzie wyglądało następująco:
Jeśli 2 pliki są rzeczywiście osobnymi plikami, takimi jak:
Można je łączyć razem z
paste
poleceniem w następujący sposób:Oto zawartość list1 i 2:
źródło
join
je pierwszy.paste
aby połączyć 2 pliki? Czy to sprawi, że nie będziesz głosować?