GNU/Linux >> Znalost Linux >  >> Linux

Porovnat dva sloupce různých souborů a vytisknout, pokud se shodují?

Používám Solaris 10, takže možnosti grep zahrnující -f nefungují.

Mám dva soubory oddělené svislou čarou:

soubor1:

abc|123|BNY|apple|
cab|234|cyx|orange|
def|kumar|pki|bird|

soubor 2:

abc|123|
kumar|pki|
cab|234

Chtěl bych porovnat první dva sloupce souboru2 se souborem1 (prohledejte celý obsah souboru1 v prvních dvou sloupcích), pokud se shodují s tiskem odpovídající řádky souboru1. Potom vyhledejte druhý řádek souboru 2 a tak dále.

Očekávaný výstup:

abc|123|BNY|apple|
cab|234|cyx|orange|

Soubory, které mám, jsou obrovské a obsahují asi 400 000 řádků, takže bych rád, aby bylo provádění rychlé.

Přijatá odpověď:

K tomu byl awk navržen:

$ awk -F'|' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' file2 file1
abc|123|BNY|apple|
cab|234|cyx|orange|

Vysvětlení

  • -F'|' :nastaví oddělovač polí na | .
  • NR==FNR :NR je číslo aktuálního vstupního řádku a FNR číslo řádku aktuálního souboru. Tyto dva se budou rovnat pouze při čtení prvního souboru.
  • c[$1$2]++; next :pokud se jedná o 1. soubor, uložte 1. dvě pole do c pole. Potom přeskočte na další řádek, aby se to použilo pouze na 1. soubor.

  • c[$1$2]>0 :blok else bude proveden pouze v případě, že se jedná o druhý soubor, takže zkontrolujeme, zda pole 1 a 2 tohoto souboru již byla zobrazena (c[$1$2]>0 ) a pokud byly, vytiskneme řádek. V awk , výchozí akcí je vytisknout řádek, takže pokud c[$1$2]>0 je true, řádek se vytiskne.

Případně, protože jste označili Perlem:

perl -e 'open(A, "file2"); while(<A>){/.+?|[^|]+/ && $k{$&}++};
         while(<>){/.+?|[^|]+/ && do{print if defined($k{$&})}}' file1

Vysvětlení

První řádek otevře file2 , přečtěte si vše až do 2. | (.+?|[^|]+ ) a uložte jej ($& je výsledkem operátoru poslední shody) v %k hash.

Druhý řádek zpracovává soubor1, používá stejný regulární výraz k extrakci prvních dvou sloupců a vytiskne řádek, pokud jsou tyto sloupce definovány v %k hash.

Oba výše uvedené přístupy budou muset držet 2 první sloupce souboru2 v paměti. To by neměl být problém, pokud máte jen několik set tisíc řádků, ale pokud ano, můžete udělat něco jako

cut -d'|' -f 1,2 file2 | while read pat; do grep "^$pat" file1; done

Ale to bude pomalejší.

Související:Zkopírovat všechny nainstalované programy a soubory na pevný disk (který má 32bitový Windows 7) a naklonovat/přenést jej do jiného počítače, který má 64bitový Windows 7?
Linux
  1. Jak porovnat tři soubory v Linuxu pomocí nástroje diff3

  2. Tisknout čáry mezi (a vyjma) dvěma vzory?

  3. Tisknout čáry mezi (a včetně) dvěma vzory?

  1. Tisknout dva soubory ve dvou sloupcích?

  2. Tisknout odpovídající čáru a N-tou čáru ze shodné čáry?

  3. Jak porovnat dva soubory a poté připojit řádek, který není částečnou shodou?

  1. Graficky porovnejte soubory a složky v Linuxu s Meldem

  2. Hledat textové soubory, kde existují dvě různá slova (jakékoli pořadí, libovolný řádek)?

  3. Společné řádky mezi dvěma soubory?