[+] Bash, porównanie zawartości plików
: 21 marca 2013, 20:07
Witam.
Chcę sobie napisać skrypt (w zasadzie to jeden kawałek, bo resztę mam). Są dwa pliki, zwykłe tekstowe:
Plik A:
Plik B:
Pliki te generowane są automatycznie, jak widać bardzo podobne. W czym rzecz? Postaram się wyjaśnić w miarę krótko i zwięźle. Potrzeba zrobić taki manewr:
Linia numer 1 i linia numer 2 w pliku A są identyczne jak np. linia 7 i 8 w pliku B, to należy je usunąć z pliku B. Tu akurat nie ma problemu, proste jest.
Mam to zrobione tak:
Ale jeżeli trafi się taki przypadek:
W pliku A mamy np.:
W pliku B:
Jak widać linijka z Nazwa jest tu i tu taka sama, ale różni się linia Numery. I tu zaczynają się schody - jeżeli trafi się takie coś, to należy to zostawić w pliku B, obydwie linie. I tego nie wiem jak zrobić, niestety. Poprosiłbym o jakieś sugestie?
Najprostsze co mi przychodzi do głowy, to właśnie porównywanie linii parami, tylko nie wiem jak to wykonać. W sensie biorę dwie linijki z jednego pliku i porównuję z dwoma z drugiego pliku, taki zmodyfikowany while read line; do ...
Edycja:
Wymyśliłem sobie też coś takiego, co mogłoby uprościć ten proces - czyli połączenie tych dwóch linijek w jedną, np.
Wtedy można by to załatwić jednym while read line... Ale nie wiem dlaczego, kiedy wyciągnę linijki parzyste, potem nieparzyste i próbuję je scalić poleceniem
to wychodzi mi jakaś dziwna masakra - linie nieparzyste pozostają na swoich miejscach, natomiast parzyste mają dodaną na początku spację.
Edycja 2:
Wydaje się, że rozwiązałem problem tego, że się kaszana działa. Otóż w pliku oprócz znaku końca linii " \n ", był jeszcze znak " \r ".
Dowiedziałem się o tym z pomocą Google i znajdując polecenie:
Usunąłem znaki robiąc:
Teraz powinno pójść wszystko załatwić jedną sprytną pętelką. Nie ma to jak przesiedzieć przy jakimś skrypcie trochę czasu, tyle się człowiek nowych rzeczy może nauczyć
Chcę sobie napisać skrypt (w zasadzie to jeden kawałek, bo resztę mam). Są dwa pliki, zwykłe tekstowe:
Plik A:
Kod: Zaznacz cały
Nazwa:aaabbbccc
Numery: abc-131 cde-476
Nazwa:ggghhhjjj
Numery: hjk-789 drt-552
...
Plik B:
Kod: Zaznacz cały
Nazwa:aaabbbccc
Numery: abc-131 cde-476
Nazwa:ggghhhjjj
Numery: hjk-789 drt-552 rty-492
...
Pliki te generowane są automatycznie, jak widać bardzo podobne. W czym rzecz? Postaram się wyjaśnić w miarę krótko i zwięźle. Potrzeba zrobić taki manewr:
Linia numer 1 i linia numer 2 w pliku A są identyczne jak np. linia 7 i 8 w pliku B, to należy je usunąć z pliku B. Tu akurat nie ma problemu, proste jest.
Mam to zrobione tak:
Kod: Zaznacz cały
while read line; do
grep -q "$line" B
if [ "$?" == 0 ] ; then
sed -i /"$line"/d B
fi
done<A
Ale jeżeli trafi się taki przypadek:
W pliku A mamy np.:
Kod: Zaznacz cały
Nazwa:aaabbbccc
Numery: abc-131 cde-476
...
W pliku B:
Kod: Zaznacz cały
Nazwa:aaabbbccc
Numery: abc-131 cde-476 wrt-345
...
Jak widać linijka z Nazwa jest tu i tu taka sama, ale różni się linia Numery. I tu zaczynają się schody - jeżeli trafi się takie coś, to należy to zostawić w pliku B, obydwie linie. I tego nie wiem jak zrobić, niestety. Poprosiłbym o jakieś sugestie?
Najprostsze co mi przychodzi do głowy, to właśnie porównywanie linii parami, tylko nie wiem jak to wykonać. W sensie biorę dwie linijki z jednego pliku i porównuję z dwoma z drugiego pliku, taki zmodyfikowany while read line; do ...
Edycja:
Wymyśliłem sobie też coś takiego, co mogłoby uprościć ten proces - czyli połączenie tych dwóch linijek w jedną, np.
Kod: Zaznacz cały
Nazwa:aaabbbccc Numery: abc-131 cde-476
Wtedy można by to załatwić jednym while read line... Ale nie wiem dlaczego, kiedy wyciągnę linijki parzyste, potem nieparzyste i próbuję je scalić poleceniem
Kod: Zaznacz cały
paste --delimiter=' ' plik_zawierający_linie_nieparzyste plik_zawierający_linie_parzyste > plik_wyjsciowy
Edycja 2:
Wydaje się, że rozwiązałem problem tego, że się kaszana działa. Otóż w pliku oprócz znaku końca linii " \n ", był jeszcze znak " \r ".
Dowiedziałem się o tym z pomocą Google i znajdując polecenie:
Kod: Zaznacz cały
od -c [I]plik[/I]
Usunąłem znaki robiąc:
Kod: Zaznacz cały
tr -d '\r' < plik > plik2
Teraz powinno pójść wszystko załatwić jedną sprytną pętelką. Nie ma to jak przesiedzieć przy jakimś skrypcie trochę czasu, tyle się człowiek nowych rzeczy może nauczyć
