Portál AbcLinuxu, 10. května 2025 05:56

Dotaz: porovnání 2 souborů

5.1.2006 13:28 Karel Borkovec | skóre: 28 | blog: HP_NX9010 | Tábor
porovnání 2 souborů
Přečteno: 422×
Odpovědět | Admin
Dobrý den. Mám 2 soubory:
aaa;200
bbbb;350
cc;467
a druhý:
aaa;1
bbbb;2
cc;3
Potřeboval bych je porovnat a vytvořit třetí soubor který bude vypadat takto:
1;aaa;200
2;bbbb;350
3;cc;467
Půjde to nějak jednoduše v bashi nebo awkem?
Nástroje: Začni sledovat (2) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

5.1.2006 14:08 slano | skóre: 5
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Odpovědět | | Sbalit | Link | Blokovat | Admin
toto by mohlo nakopnut:
#!/bin/sh

cat $1 |while read line1
do
  pattern=`echo $line1 | cut -f 1 -d ";"`
  line2=`grep $pattern $2`
  echo `echo $line2 | cut -f 2 -d ";"`";$line1"
done
ako parameter tomu daj prvy a druhy subor, este je potrebne osetrovat return code grepu (ak by nahodou nenaslo hladany vzor v druhom subore, neviem ako to chces)
5.1.2006 14:20 Karel Borkovec | skóre: 28 | blog: HP_NX9010 | Tábor
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Sorry uvedl sem špatný příklad, toto by fungovalo dobře, kdyby vždy souvisel první řádek v prvním souboru s prvním řádkem v druhém souboru... ale když to bude takto:
aaa;200
bbbb;350
cc;467
a druhý:
cc;1
aaa;2
bbbb;3
Tzn. když to bude různě proházené, tak ten skriptík nedube fungovat, proto sem psal v nadpisu "porovnání" souborů... Doufám, že jsem to napsal srozumitelně...
5.1.2006 14:55 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Hmm, tak to jsi měl říct hned :-)
join -t ';' -o '2.2 1.1 1.2' <(sort file1) <(sort file2)
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
5.1.2006 15:18 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Pokud nemáš bash, ale pouze sh, tak ekvivalentní je
mkfifo fifo1 fifo2
sort <file1 >fifo1 &
sort <file2 >fifo2 &
join -t ';' -o '2.2 1.1 1.2' fifo1 fifo2
rm fifo1 fifo2
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
5.1.2006 15:22 Karel Borkovec | skóre: 28 | blog: HP_NX9010 | Tábor
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Mám bash i sh, díky moc! Funguje to dobře!
5.1.2006 16:25 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Teda nevím jako moc velké jsou ty soubory, ale pro hodně velké soubory by byl rychlejší perl. Třeba trošku brutal oneliner
 perl -e 'sub p(){chomp;split /;/, $_, 2} open F, "<$ARGV[0]"; while(<F>){($k,$v) = p; $t{$k}=$v} close F; open F, "<$ARGV[1]"; while(<F>){($k,$v) = p;  print "$v;$k;$t{$k}$/"} close F' file1 file2
případně jako script
#!/usr/bin/env perl
@ARGV >= 2 or die 'Not enough paramters';
sub p () {
  chomp;
  split /;/, $_, 2
}
open F, "<$ARGV[0]" or die "Can't open $ARGV[0] for readin";
while(<F>){
  ($k,$v) = p;
  $t{$k}=$v
}
close F;
open F, "<$ARGV[1]" or die "Can't open $ARGV[1] for readin";
while(<F>){
  ($k,$v) = p;
  print "$v;$k;$t{$k}$/"
} close F
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
5.1.2006 21:33 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Ještě kratší perl oneliner, aneb vychutnejte sílu perlu
perl -e 'sub p(&$){open F, shift @ARGV;while(<F>){chomp;($k,$v)=split /;/,$_,2;&{$_[0]}}close F}p{$t{$k}=$v};p{print "$v;$k;$t{$k}$/"}' file1 file2
Je fakt, že to jde určitě napsat ještě méně čitelně, ale na mistry oboru ještě dlouho mít nebudu.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
5.1.2006 21:39 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Oh, chybička se vloudila
perl -e 'sub p(&){open F,shift @ARGV;while(<F>){chomp;($k,$v)=split /;/,$_,2;&{$_[0]}}close F}p{$t{$k}=$v};p{print "$v;$k;$t{$k}$/"}' file1 file2
Kdo chce ušetřit ještě pár znaků, může vynechat close F :-)
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
David Watzke avatar 5.1.2006 22:11 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Wow a tohle dáváš opravdu jen tak z hlavy? Ani to nemusíš zkoušet?
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
5.1.2006 22:20 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
No jasně, při troše praxe to jde samo :-)
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
5.1.2006 15:06 slano | skóre: 5
Rozbalit Rozbalit vše Re: porovnání 2 souborů
no, dovolim si tvrdit ze fungovat bude ;) kazdopadne join je elegantnejsie riesenie
5.1.2006 15:08 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Kromě toho, že tahle implementace je silně suboptimální, protože se ten druhý soubor čte tolikrát, kolik je počet řádků prvního souboru je ten shell pěkně nevyužitej.
IFS=';'
while read key rest
do
  echo "$rest;$(grep "^$key;" "$1")"
done <"$2"
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
6.1.2006 16:21 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Tak jde to implementovat i bashi stejně jednoprůchodově.
uniqprefix=yuwg
IFS=';'
while read key rest
do
  eval "$uniqprefix$key=$rest"
done <"$1"
while read key rest
do
  var="$uniqprefix$key"
  [ -n "${!var}" ] && echo "$rest;$key;${!var}"
done <"$2"
Dvě drobné záludnosti, je nutnost definovat jednoznačný prefix a první cyklus se nesmí spustit jako subproces. Takže ani žádné roury. Jde to samozřejmě vyřešit pro bash (... done < <(filter "$1")) i pro sh (teda pokud to celé vůbec v sh funguje).
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
5.1.2006 14:32 Michal Čihař | skóre: 61 | blog: Bláboly | Praha
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Odpovědět | | Sbalit | Link | Blokovat | Admin
join(1)?
Weblate - překládání přes web | Gammu SMSD - posílání SMS | Blog
5.1.2006 14:47 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Odpovědět | | Sbalit | Link | Blokovat | Admin
join -t ';' -o '2.2 1.1 1.2' file1 file2
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
5.1.2006 14:51 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Oneliner demonstration (only for bash):
join -t ';' -o '2.2 1.1 1.2' <(echo -e 'aaa;200\nbbbb;350\ncc;467') <(echo -e 'aaa;1\nbbbb;2\ncc;3')
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
5.1.2006 20:47 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Odpovědět | | Sbalit | Link | Blokovat | Admin

To je zajímavé, kolik je na jeden problém řešení. Ještě tu nebyl awk, zde tedy je:

cat vstup1.txt vstup2.txt | awk '
BEGIN { FS = ";" }
/^$/ { druhySoubor = 1; }
/.+/ { if ( druhySoubor ) { pole[ $1 ] = $2 ";" pole[ $1 ]; } else { pole[ $1 ] = $0; } }
END  { for ( i in pole ) { print pole[ i ]; } } ' | \
sort -n -t";" -k1

5.1.2006 21:18 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Tak ten problém s přidáním prázdného řádku i s vyloučením prázdných řádků ve vstupních souborech jde taky udělat takto
(egrep -v '^$' file1; echo; egrep -v '^$' file2) |
awk ...
Ale musím uznat, že to už je fakt maso :-) Nadruhou stranu by to mělo být srovnatelné s tím řešením v perlu.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
6.1.2006 17:39 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Tak to je ovšem pěkně hustý! To mě nenapadlo. Ale kratší než join to už stejně nevymyslíme...
5.1.2006 22:07 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: porovnání 2 souborů
Tenhle algoritmus jde udělat i v perlu a je to dokonce kratší než perlish řešení
perl -ne 'chomp;m/^$/&&++$d&&next;($k,$v)=split /;/,$_,2;$d?print "$v;$k;$t{$k}$/":($t{$k}=$v)'
Osobně se mi to ale moc nelíbí.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.