Strona 1 z 1

[bash] wyciąganie różnic z plików

: 11 sie 2009, 12:21
autor: alhaim
Witam,
mam następujący problem -- mam 2 pliki: A i B, oba tekstowe, z danymi w wierszach. Chcę na ich podstawie utworzyć dwa nowe pliki X i Y, takie że:
X zawiera tylko te wiersze, które są w pliku A, a nie występują w B;
Y zawiera tylko te wiersze, które są w pliku B, a nie występują w A;

Za wszelką pomoc będę bardzo wdzięczny.

Odp: [bash] wyciąganie różnic z plików

: 11 sie 2009, 23:25
autor: Tomasz_K
Napisz coś więcej o tym projekcie??

Odp: [bash] wyciąganie różnic z plików

: 12 sie 2009, 09:49
autor: kabanek
@Tomasz_K
problem jest jasno przedstawiony

a jak dobrze umiesz basha? Bo my tu nie jesteśmy po to, żeby rozwiązywać za Ciebie problemy, tylko żeby pomóc i naprowadzić na dobre rozwiązanie.

Ja algorytm mam taki:
1. wprowadzasz wszystkie wiersze z pliku A do tablicy (nazwijmy ją tablica_A), przy czym zliczasz ile tych wierszy było
2. tworzysz 2 tablicę n elementową (n - liczba wierszy w pliku A) i zapisujesz tam wszędzie tak (true) Będzie to dla nas informacja, które wiersze z pliku A się nie powtarzały. Nazwijmy ją tablica_TAK
3. wczytujesz 1 linię z pliku B
3a. przechodzisz przez całą tablicę tablica_A, i sprawdzasz, czy gdzieś tam występuje, to co przed chwilą wczytałeś
3b. Jeśli tak, to zaznaczasz na i-tym indeksie na 'nie', czyli (w pseudokodzie)

Kod: Zaznacz cały

wczytaj(wczytana);
od 0 do n-1
   jesli tablica_A[i] == wczytana
      tablica_TAK[i] = nie;
3c. Jeśli natomiast przejdzie przez całą tablicę tablica_A, to znak, że jej w pliku A nie ma, czyli zapisujemy do pliku Y
4. Gdy skończy się plik B, to przechodzisz przez tablicą tablica_TAK i jeśli na i-tym miejscu jest 'tak', to ten wiersz zapisujemy do pliku X

Kod: Zaznacz cały

od 0 do n-1
   jesli tablica_TAK[i] == tak
      zapisz_do_pliku(tablica_A[i]);
czy cos w tym stylu :)

Odp: [bash] wyciąganie różnic z plików

: 12 sie 2009, 14:38
autor: leon1313
Myślę, że o wiele lepiej wypadłoby to przy połączeniu PERL+ MySQL ( złączenia zewnetrzne)

Odp: [bash] wyciąganie różnic z plików

: 12 sie 2009, 15:00
autor: alhaim
leon1313 pisze:Myślę, że o wiele lepiej wypadłoby to przy połączeniu PERL+ MySQL ( złączenia zewnetrzne)
Nie znam niestety PERLa. Spróbuję pomysłu Kabanka ze stablicowaniem całości, robiłem już coś podobnego, ale zamiast tablic zrobiłem podwójnego for w stylu

Kod: Zaznacz cały

for f in `cat plik`; do
   for g in `cat plik2`; do
...
   done
done
ale to nie jest dobre rozwiązanie (oba pliki mają ~2500 wierszy).

Z tego co zauważyłem to dużo szybciej jest zastosowanie grepa jeśli chcemy sprawdzić, czy dany iwersz występuje w dwu plikach jednocześnie. Jednak nie wiem jak zastosować grepa do różnicy.

Odp: [bash] wyciąganie różnic z plików

: 12 sie 2009, 15:22
autor: Dwimenor
Zobacz sobie na jakiś mniejszych plikach

Kod: Zaznacz cały

diff -y plik_a plik_b
Może ci coś przyjdzie do głowy. Można posprawdzać w których linijkach są znaki > i < i te linijki przekopiować do plików X i Y

Odp: [bash] wyciąganie różnic z plików

: 12 sie 2009, 18:24
autor: leon1313
PERL ze względu na szybkośc obróbki plików tekstowych, ale równie dobrze może to być bash.
Wrzucasz 2 pliki do różnych tabel, dodajesz pole index (autoincrement), porównujesz (łączysz) za pomocą "LEFT OUTER JOIN" i szukasz wartości null.
Jak pokombinujesz z funkcjami i widokami to będziesz miał porządne narzędzie do porównywania.

Odp: [bash] wyciąganie różnic z plików

: 12 sie 2009, 19:11
autor: dk75

Kod: Zaznacz cały

diff -iwbBaf plik_1 plik_2 |awk '!/a[[:digit:]]/ && !/d[[:digit:]]/ {print}'
i

Kod: Zaznacz cały

diff -iwbBaf plik_2 plik_1 |awk '!/a[[:digit:]]/ && !/d[[:digit:]]/ {print}'
ale pozostają jeszcze kropki jednak wprowadzenie warunku "&& !/^\./" spowoduje wykasowanie każdej linijki zaczynającej się kropką