Zasadniczo chcę więc porównać dwa pliki wiersz po kolumnie 2. Jak to zrobić?
Plik_1.txt:
User1 US
User2 US
User3 US
Plik_2.txt:
User1 US
User2 US
User3 NG
Plik wyjściowy:
User3 has changed
command-line
text-processing
Roboman1723
źródło
źródło
diff "File_1.txt" "File_2.txt"
Odpowiedzi:
Sprawdź
diff
polecenie. To dobre narzędzie i możesz o tym przeczytać, piszącman diff
na terminalu.Polecenie, które chcesz wykonać,
diff File_1.txt File_2.txt
spowoduje wyświetlenie różnicy między nimi i powinno wyglądać mniej więcej tak:Szybka uwaga na temat odczytu wyniku trzeciego polecenia: „Strzałki” (
<
i>
) odnoszą się do wartości wiersza w lewym pliku (<
) w porównaniu do prawego pliku (>
), przy czym lewy plik to ten, który wprowadziłeś najpierw w wierszu poleceń, w tym przypadkuFile_1.txt
Dodatkowo można zauważyć 4. Polecenie to jest
diff ... | tee Output_File
to rury wyniki uzyskanediff
wtee
, który wykłada, że wyjście do pliku, tak aby można go zapisać na później, jeśli nie chcemy, aby to wszystko zobaczyć po prawej stronie konsoli tego drugiego.źródło
diff file1 file2 -s
. Oto przykład: imgur.com/ShrQx9xLub możesz użyć Meld Diff
Zainstaluj, uruchamiając:
Twój przykład:
Porównaj katalog:
Przykład z pełnym tekstem:
źródło
Możesz użyć vimdiff .
Przykład:
źródło
dos
a drugi wunix
.FWIW, raczej podoba mi się to, co otrzymuję z wyjściowym wyjściem z diff
dałby coś takiego:
źródło
Możesz użyć polecenia
cmp
:wyjście byłoby
źródło
cmp
jest znacznie szybszy niżdiff
gdyby wszystko, czego chcesz, to kod powrotu.Meld
to naprawdę świetne narzędzie. Ale możesz także użyćdiffuse
do wizualnego porównania dwóch plików:źródło
Przyklejając się do pytania (plik1, plik2, plik wyjściowy z komunikatem „zmieniłem”) poniższy skrypt działa.
Skopiuj skrypt do pustego pliku, zapisz go jako
compare.py
, wykonaj go, uruchom za pomocą polecenia:Scenariusz:
Za pomocą kilku dodatkowych wierszy możesz wydrukować plik wyjściowy lub terminal, w zależności od tego, czy plik wyjściowy jest zdefiniowany:
Aby wydrukować do pliku:
Aby wydrukować do okna terminala:
Scenariusz:
źródło
Prostym sposobem jest użycie
colordiff
, które zachowuje się jak,diff
ale koloruje jego wynik. Jest to bardzo pomocne przy czytaniu różnic. Korzystając z twojego przykładu,gdzie
u
opcja daje zunifikowaną różnicę. Tak wygląda pokolorowany plik różnicowy:Zainstaluj
colordiff
, uruchamiającsudo apt-get install colordiff
.źródło
Dodatkowa odpowiedź
Jeśli nie musisz wiedzieć, które części plików się różnią, możesz użyć sumy kontrolnej pliku. Można to zrobić na wiele sposobów, używając
md5sum
lubsha256sum
. Zasadniczo każdy z nich wyświetla ciąg znaków, do którego hash zawartości pliku. Jeśli oba pliki są takie same, ich skrót również będzie taki sam. Jest to często używane podczas pobierania oprogramowania, takiego jak obrazy ISO instalacji Ubuntu. Są często używane do sprawdzania integralności pobranych treści.Rozważ poniższy skrypt, w którym możesz podać dwa pliki jako argumenty, a plik powie ci, czy są takie same, czy nie.
Przykładowy przebieg:
Starsza odpowiedź
Ponadto istnieje
comm
polecenie, które porównuje dwa posortowane pliki i daje wynik w 3 kolumnach: kolumna 1 dla elementów unikalnych dla pliku nr 1, kolumna 2 dla elementów unikalnych dla pliku nr 2 i kolumna 3 dla elementów obecnych w obu plikach.Aby pominąć dowolną kolumnę, możesz użyć przełączników -1, -2 i -3. Użycie -3 pokaże linie, które się różnią.
Poniżej możesz zobaczyć zrzut ekranu polecenia w akcji.
Jest tylko jeden wymóg - pliki muszą być posortowane, aby można je było poprawnie porównać.
sort
w tym celu można użyć polecenia. Poniżej znajduje się inny zrzut ekranu, w którym pliki są sortowane, a następnie porównywane. Linie zaczynające się od lewej bellong tylko do pliku_1, linie zaczynające się w kolumnie 2 należą tylko do pliku_2źródło
Zainstaluj git i użyj
Otrzymasz wyjście w ładnym, kolorowym formacie
Instalacja Git
źródło
colcmp.sh
Porównuje pary nazwa / wartość w 2 plikach w formacie
name value\n
. Zapisujename
do,Output_file
jeśli zmieniono. Wymaga bash v4 + dla tablic asocjacyjnych .Stosowanie
Plik wyjściowy
Źródło (colcmp.sh)
Wyjaśnienie
Podział kodu i jego znaczenie, o ile mi wiadomo. Z zadowoleniem przyjmuję zmiany i sugestie.
Podstawowe porównanie plików
cmp ustawi wartość $? w następujący sposób :
Zdecydowałem się użyć instrukcji case .. esac do oceny $? ponieważ wartość $? zmienia się po każdym poleceniu, w tym test ([).
Alternatywnie mogłem użyć zmiennej do przechowywania wartości $? :
Powyżej robi to samo co instrukcja case. IDK, który lubię bardziej.
Wyczyść dane wyjściowe
Powyżej usuwa plik wyjściowy, więc jeśli żaden użytkownik się nie zmieni, plik wyjściowy będzie pusty.
Robię to wewnątrz instrukcji case , aby plik wyjściowy pozostał niezmieniony po błędzie.
Skopiuj plik użytkownika do skryptu powłoki
Powyżej kopiuje plik_1.txt do katalogu domowego bieżącego użytkownika.
Na przykład, jeśli bieżącym użytkownikiem jest John, powyższe byłoby takie samo jak cp „File_1.txt” /home/john/.colcmp.arrays.tmp.sh
Ucieczka ze znaków specjalnych
Zasadniczo jestem paranoikiem. Wiem, że te znaki mogą mieć specjalne znaczenie lub wykonywać zewnętrzny program, gdy są uruchamiane w skrypcie w ramach przypisywania zmiennych:
Co ja nie wiem , jak bardzo nie wiem o bash. Nie wiem, jakie inne postacie mogą mieć specjalne znaczenie, ale chcę uciec przed nimi wszystkimi odwrotnym ukośnikiem:
sed potrafi znacznie więcej niż dopasowywanie wzorców wyrażeń regularnych . Wzorzec skryptu „s / (find) / (replace) /” konkretnie wykonuje dopasowanie wzorca.
„s / (znajdź) / (zamień) / (modyfikatory)”
w języku angielskim: przechwytuj dowolne znaki interpunkcyjne lub specjalne jako grupę kaputur 1 (\\ 1)
w języku angielskim: poprzedź wszystkie znaki specjalne odwrotnym ukośnikiem
w języku angielskim: jeśli w tym samym wierszu znaleziono więcej niż jedno dopasowanie, zamień je wszystkie
Skomentuj cały skrypt
Powyżej używa wyrażenia regularnego, aby poprzedzić każdą linię ~ / .colcmp.arrays.tmp.sh znakiem komentarza bash ( # ). Robię to, ponieważ później zamierzam wykonać ~ / .colcmp.arrays.tmp.sh za pomocą polecenia source i ponieważ nie wiem na pewno cały format pliku_1.txt .
Nie chcę przypadkowo wykonać dowolnego kodu. Nie sądzę, żeby ktokolwiek to zrobił.
„s / (znajdź) / (zamień) /”
w języku angielskim: przechwytuj każdą linię jako grupę caputure 1 (\\ 1)
w języku angielskim: zamień każdą linię na symbol funta, a następnie linię, która została zastąpiona
Konwertuj wartość użytkownika na A1 [użytkownik] = „wartość”
Powyżej znajduje się rdzeń tego skryptu.
#User1 US
A1[User1]="US"
A2[User1]="US"
(dla drugiego pliku)„s / (znajdź) / (zamień) /”
po angielsku:
przechwyć resztę linii jako grupę przechwytywania 2
(zamień) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"
A1[
aby rozpocząć przypisanie tablicy w tablicy o nazwieA1
]="
]
= bliskie przypisanie tablicy, np.A1[
Użytkownik1]="
USA"
=
= operator przypisania, np. zmienna = wartość"
= podaj wartość, aby uchwycić spacje ... chociaż teraz, gdy o tym myślę, łatwiej byłoby pozwolić kodowi powyżej, który odwraca wszystko, także do znaków odwrotnego ukośnika.w języku angielskim: zastąp każdą linię w formacie
#name value
operatorem przypisania tablicy w formacieA1[name]="value"
Uczyń plik wykonywalny
Powyżej używa chmod, aby plik skryptu tablicowego był wykonywalny.
Nie jestem pewien, czy jest to konieczne.
Zadeklaruj tablicę asocjacyjną (bash v4 +)
Wielka-A oznacza, że zadeklarowane zmienne będą tablicami asocjacyjnymi .
Dlatego skrypt wymaga bash v4 lub nowszego.
Wykonaj nasz skrypt Array Variable Assignment Script
Mamy już:
User value
na linieA1[User]="value"
,Powyżej my źródła skryptu, aby uruchomić go w bieżącej powłoki. Robimy to, abyśmy mogli zachować wartości zmiennych ustawiane przez skrypt. Jeśli skrypt zostanie wykonany bezpośrednio, odradza się nowa powłoka, a wartości zmiennych są tracone po wyjściu z nowej powłoki, a przynajmniej tak rozumiem.
To powinna być funkcja
Robimy to samo za 1 USD i A1 , co za 2 USD i A2 . To naprawdę powinna być funkcja. Myślę, że w tym momencie ten skrypt jest dość mylący i działa, więc go nie naprawię.
Wykryj usuniętych użytkowników
Powyższe pętle za pomocą kluczy tablicy asocjacyjnej
Powyżej używa podstawienia zmiennej w celu wykrycia różnicy między wartością, która nie jest ustawiona, a zmienną, która została jawnie ustawiona na ciąg o zerowej długości.
Najwyraźniej istnieje wiele sposobów sprawdzenia, czy zmienna została ustawiona . Wybrałem ten, który ma najwięcej głosów.
Powyżej dodaje użytkownika $ i do pliku_wyjściowego
Wykryj dodanych lub zmienionych użytkowników
Powyżej usuwa zmienną, dzięki czemu możemy śledzić użytkowników, którzy się nie zmienili.
Powyższe pętle za pomocą kluczy tablicy asocjacyjnej
Powyżej używa podstawienia zmiennej, aby sprawdzić, czy zmienna została ustawiona .
Ponieważ $ i jest kluczem tablicy (nazwa użytkownika) $ A2 [$ i] powinien zwrócić wartość powiązaną z bieżącym użytkownikiem z pliku_2.txt .
Na przykład jeśli $ i to Użytkownik1 , powyższy tekst brzmi jako $ {A2 [Użytkownik1]}
Powyżej dodaje użytkownika $ i do pliku_wyjściowego
Ponieważ $ i jest kluczem tablicy (nazwa użytkownika) $ A1 [$ i] powinien zwrócić wartość powiązaną z bieżącym użytkownikiem z pliku_1.txt , a $ A2 [$ i] powinien zwrócić wartość z pliku_2.txt .
Powyżej porównuje powiązane wartości dla użytkownika $ i z obu plików.
Powyżej dodaje użytkownika $ i do pliku_wyjściowego
Powyżej tworzy oddzieloną przecinkami listę użytkowników, którzy się nie zmienili. Uwaga: na liście nie ma spacji, w przeciwnym razie należałoby zacytować następny czek.
Powyżej zgłasza wartość $ USERSWHODIDNOTCHANGE, ale tylko jeśli wartość jest w US $ USERSWHODIDNOTCHANGE . Sposób zapisu: $ USERSWHODIDNOTCHANGE nie może zawierać spacji. Jeśli potrzebuje spacji, powyższe można przepisać w następujący sposób:
źródło