Nowe posty

xx Problem ze sterownikami. (5)
2024-04-13, 21:25:16
xx Instalacja xfce4 (2)
2024-04-13, 16:20:17
xx Serie kompilacji bez instalacji dla “emerge” w Gentoo (2)
2024-04-08, 18:40:04
xx Plasma 6 w Neonie ssie trochę mniej ... (17)
2024-04-05, 10:03:46
xx Problem z Linux Lite po instalacji (3)
2024-04-03, 14:23:40
xx Jak właczyć num locka przy starcie systemu debian 12? (12)
2024-04-02, 17:43:54
xx Brak dźwieku w systemie. (5)
2024-04-02, 16:13:41
xx Dystrybucja pod HP Omen (7)
2024-03-29, 11:33:05
xx [Poradnik] Wyszukiwanie Sterowników (2)
2024-03-27, 21:08:23
xx Ile pingwinów? (1)
2024-03-27, 08:59:24

Autor Wątek: [Bash] Skrypt porównujący dwa pliki  (Przeczytany 3089 razy)

crash

  • Gość
[Bash] Skrypt porównujący dwa pliki
« dnia: 2014-02-06, 23:21:42 »
Witajcie,
Nie jestem dobry w bash, stawiam dopiero pierwsze kroki.
Mam problem ze skryptem porównującym dwa pliki [plik1nowy, plik2stary]. Linie z pierwszego pliku [plik1nowy] mają być zapisywane do nowego pliku [plik3] ale przed tym musi być sprawdzony [plik2stary] czy nie zawiera już linii o takich samych ID. Jeśli tak to dane wprowadzane do nowego pliku [plik3] muszą być oznaczone specjalnie jako występujące w obu plikach. Pliki mogą mieć do 30 linii ich ilość linii nie jest dynamicznym raz mogą mieć 30 linii a innym razem 1 linie.


[plik1nowy]
Godzina | Imię | Nazwisko | ID1 | ID2

[plik2stary]
Godzina | Imię | Nazwisko | ID1 | ID2

[plik3]
Godzina | Imię | Nazwisko | ID1 | ID2


Napisałem skrypt porównujący dwa pliki, ale zastanawiam się czy nie można łatwiej ponieważ strasznie topornie to wyszło.

1. Na początku aby porównać czy dana linijka nie występuje w drugim pliku zliczam linijki w każdym z plików:

licz2=`cat -n plik2stary | tail -1 | awk '{print $1}'`
echo $licz2
if [ $licz2 = 1 ]; then
  echo Log zawiera 1 linie
elif [ $licz2 = 2 ]; then
  echo Log zawiera 2 linie
...
if

licz1=`cat -n plik1nowy | tail -1 | awk '{print $1}'`
echo $licz1
if [ $licz1 = 1 ]; then
  echo Log zawiera 1 linie
elif [ $licz1 = 2 ]; then
  echo Log zawiera 2 linie
...
if
2. Wiedząc ile mamy linii w starym i nowym pliku mogę zaczytać dane tylko ID1 i ID2 z obu plików:

licz2_line2=`awk -F| 'FNR == 2{print $4 $5}' < plik2stary`
licz2_line3=`awk -F| 'FNR == 3{print $4 $5}' < plik2stary`
...

licz1_line2=`awk -F| 'FNR == 2{print $4 $5}' < plik1nowy`
licz1_line3=`awk -F| 'FNR == 3{print $4 $5}' < plik1nowy`
...
3. I teraz porównanie które zrobiłem:

if [ "$licz1_line2" = "$licz2_line2" ]; then
  echo $licz1_line2 jest równa $licz2_line2
else
  echo $licz1_line2 jest rożna od $licz2_line2
fi
if [ "$licz1_line2" = "$licz2_line3" ]; then
  echo $licz1_line2 jest równa $licz2_line3
else
  echo $licz1_line2 jest rożna od $licz2_line3
...
fi
Robiąc każdy przypadek [do 30 linii] moja metoda jest bardzo karkołomna, czasochłonna i mało efektywna. Dlatego zwracam się z pytaniem czy istnie jakaś prostsza metoda aby uzyskać taki efekt może tablice? Proszę o pomoc.

Offline ultr

  • Users
  • Guru
  • *****
  • Wiadomości: 1177
    • Zobacz profil
[Bash] Skrypt porównujący dwa pliki
« Odpowiedź #1 dnia: 2014-02-07, 12:30:34 »
Wczytujesz linia po linii 1 plik:
while read -r line; do
  ...
done < plik1.txt
W pętli dla każdej linii wyciągasz cut-em albo czymkolwiek innym końcówkę linii zawierającą oba ID i zapisujesz w stringu:
  IDs=...
Grep-ujesz plik2.txt czy zawiera na końcu linii (regexp, opcja -E) znaleziony wcześniej ciąg IDs.
Sprawdzasz kod wyjścia ($?, albo test-em ([...]) samego grep-a) i, jeśli nie zawiera, to wyświetlasz (echo) normalnie linię, a jeśli tak to np. dopisujesz na jej końcu jakieś oznaczenie.
Całość wysyłasz do plik3.txt:
while read -r line; do
  ...
done < plik1.txt > plik3.txt