2012-05-18 13 views
5

Mam dwa pliki z posortowanymi liniami. Jeden plik (B) jest podzbiorem drugiego pliku (A). Chciałbym znaleźć wszystkie linie w A, które NIE SĄ w B. Idealnie, chciałbym stworzyć plik (C), który zawiera te linie. Czy to możliwe w systemie Unix? Poszukuję polecenia jednego wiersza, aby to zrobić zamiast pisać skrypt. Spojrzałem na polecenia join i diff, ale nie mogłem znaleźć opcji polecenia, aby to zrobić. Dzięki za pomoc.Jak znaleźć zestaw - podzbiór dwóch plików z wiersza poleceń?

Odpowiedz

12

To będzie tłumić wspólne linie:

comm -3 a b 
+1

A w przypadku chcesz kiedykolwiek, aby znaleźć wspólne linie w obu plikach, można użyć 'komunikator -12 ab' – voithos

+0

Aby utworzyć trzeci plik c należałoby użyć oczywiście' comm -3 ab> c' – 0x4a6f4672

3

Można to zrobić z diff również. Różnica (w przeciwieństwie do użytkownika @ johlo grep odpowiedzi) troszczy się o zamówienie, działa na plikach nie segregowanych (w przeciwieństwie do użytkownika @ johnshen64 komunikatora odpowiedź):

$ cat a 
a 
b 
c 
d 
e 
$ cat b 
a 
b 
f 
d 
e 
$ diff -dbU0 a b 
--- a 2012-05-18 16:02:30.603386016 -0400 
+++ b 2012-05-18 16:02:45.547817122 -0400 
@@ -3 +3 @@ 
-c 
+f 

Więc można użyć rurociągu dostać tylko pominięte linie-rozważają zamówienie:

$ diff -dbU0 a b | tail -n +4 | grep ^- | cut -c2- 
c 
0

awk Rozwiązanie

pliki wejściowe

aaa 
bbb 
ccc 

b

ccc 
ddd 
eel 

kod

awk ' NR==FNR { A[$0]=1; next; } 
{ if ($0 in A) { A[$0]=0; } } 
END { for (k in A) { if (A[k]==1) { print k; } } } ' a b > c 

C (plik wyjścia)

bbb 
aaa 
+0

OP specjalnie proszony o rozwiązanie nie-skryptowe. Biorąc pod uwagę, umieściłeś skrypt w wierszu poleceń, ale ... – derobert

1

Polecenie join zrobi to pytasz:

join -v 1 fileA fileB > fileC 

Demonstrację:

$ cat fileA 
a 
c 
d 
g 
h 
t 
u 
v 
z 
$ cat fileB 
a 
d 
g 
t 
u 
z 
$ join -v 1 fileA fileB 
c 
h 
v 

Zakłada pliki posortowane jak stwierdził w swoim pytaniu. Dla nieposortowane plików:

join -v 1 <(sort fileA) <(sort fileB) 
Powiązane problemy