Mam serię plików tekstowych, dla których chciałbym znać wiersze wspólne, a nie różne między nimi. Unix lub Windows z linii poleceń są w porządku.
bla:
linux-vdso.so.1 => (0x00007fffccffe000)
libvlc.so.2 => /usr/lib/libvlc.so.2 (0x00007f0dc4b0b000)
libvlccore.so.0 => /usr/lib/libvlccore.so.0 (0x00007f0dc483f000)
libc.so.6 => /lib/libc.so.6 (0x00007f0dc44cd000)
bar:
libkdeui.so.5 => /usr/lib/libkdeui.so.5 (0x00007f716ae22000)
libkio.so.5 => /usr/lib/libkio.so.5 (0x00007f716a96d000)
linux-vdso.so.1 => (0x00007fffccffe000)
Tak więc, biorąc pod uwagę, że te dwa pliki powyżej danych wyjściowych pożądanego narzędzia byłyby podobne file1:line_number, file2:line_number == matching text
(tylko sugestia, naprawdę nie obchodzi mnie, jaka jest składnia):
foo:1, bar:3 == linux-vdso.so.1 => (0x00007fffccffe000)
dzięki.
command-line
diff
Matt Wilkie
źródło
źródło
Odpowiedzi:
Na * nix możesz użyć comm . Odpowiedź na pytanie brzmi:
Oto pełne wykorzystanie
comm
:Zauważ również, że ważne jest, aby posortować pliki przed użyciem comm, jak wspomniano na stronach podręcznika.
źródło
Znalazłem tę odpowiedź na pytanie wymienione jako zduplikowane . Uważam, że grep jest bardziej przyjazny dla administratora niż comm, więc jeśli chcesz tylko zestaw pasujących wierszy (przydatnych na przykład do porównywania plików CSV), po prostu użyj
lub uproszczona wersja fgrep
Ponadto możesz użyć
file2*
do globowania i szukać linii wspólnych dla wielu plików, a nie tylko dwóch.Inne przydatne odmiany to
-n
flaga, aby pokazać numer każdego dopasowanego wiersza-c
aby policzyć tylko liczbę pasujących wierszy-v
aby wyświetlić tylko te wiersze w pliku2, które się różnią (lub używajądiff
).Korzystanie
comm
jest szybsze, ale odbywa się to kosztem konieczności sortowania plików. Nie jest zbyt przydatna jako „odwrotna różnica”.źródło
-v
flagi po tym, jak sam się z nią pomyliłem. Załóżmy, że masz dwa pliki csv plik1 i plik2 i mają one zarówno nakładające się, jak i nienakładające się wiersze. Jeśli chcesz mieć wszystkie i tylko nienakładające się wiersze, użyciefgrep -v file1 file2
zwróci tylko nienakładające się wiersze w pliku2 i żadne dodatkowe nienakładające się wiersze w pliku1 . Dla niektórych może to być oczywiste, ale lepiej powiedzieć to, co oczywiste, niż ryzykować błędną interpretację. W tym konkretnym przypadku sortowanie plików i używaniecomm
jest nadal lepszym wyborem.grep
: każda pusta linia w pierwszym pliku będzie pasować do każdej linii w drugim pliku. Upewnij się, żefile1
nie ma pustych wierszy, w przeciwnym razie pliki będą wyglądać tak, jakby były identyczne.grep -Fxf
to jest dla mnie.Zostałem tu wcześniej zapytany: Polecenie Unix do znalezienia linii wspólnych w dwóch plikach
Możesz także spróbować z perl ( tutaj jest kredyt )
źródło
comm
nie było łatwo dostępne. To była doskonała alternatywa.Właśnie nauczyłem się polecenia comm z tego wątku, ale chciałem dodać coś więcej: jeśli pliki nie są posortowane i nie chcesz dotykać oryginalnych plików, możesz potokować wyjście polecenia sortowania. To pozostawia oryginalne pliki nienaruszone. Działa w bashu, nie mogę powiedzieć o innych muszlach.
Można to rozszerzyć, aby porównać dane wyjściowe polecenia zamiast plików:
źródło
Najłatwiej to zrobić:
Pliki nie muszą być sortowane.
źródło
Dla informacji, stworzyłem małe narzędzie dla Windows robiące to samo, co "grep -F -x -f plik1 plik2" (ponieważ nie znalazłem nic równoważnego temu poleceniu w Windows)
Oto on: http://www.nerdzcore.com/?page=commonlines
Użycie to „CommonLines plik_wejściowy1 plik_wejściowy2 plik_wyjściowy”
Kod źródłowy jest również dostępny (GPL)
źródło
W systemie Windows można użyć skryptu Powershell z CompareObject
PorównajObiekt:
źródło