Scalanie kolumn z dwóch oddzielnych plików

10

Jak utworzyć nowy plik łączący selektywne kolumny z dwóch osobnych plików za pomocą awk? Bez bałaganu zamówienia elementów OBIE pliki.

Przykład: plik 3 może zawierać kolumnę 1, 2, 3 z pliku 1 i kolumnę 4 z pliku 2.

File 1
A   23  8   T
A   63  9   9
B   45  3   J

File 2
A   0
A   6   
B   5

File 3
A   23  8   0
A   63  9   6
B   45  3   5
gołębica
źródło

Odpowiedzi:

4

Spróbuj tego:

$ awk 'FNR==NR{a[FNR]=$2;next};{$NF=a[FNR]};1' file2 file1
A 23 8 0
A 63 9 6
B 45 3 5
Cuonglm
źródło
Dzięki! Z powodzeniem wypróbowałem również tę metodę, używając gawk:pr -m -t -s\ File1.txt File2.txt | gawk '{print $1,$2,$3, $6}' > File3.txt
dovah
2
@Dovah: Możesz użyć, paste file1 file2a następnie wydrukować wybrane pola w awk.
cuonglm
Przechowuje to file2w pamięci, co może być przeszkodą, jeśli pliki są duże. Jest prostszy sposób na zrobienie tego bez narzutu pamięci (patrz moja odpowiedź).
Gilles „SO- przestań być zły”
17

Jest to specjalne narzędzie do że: paste. Łączy każdą pełną linię z pierwszego pliku z odpowiednią linią z drugiego pliku; możesz usunąć niechciane kolumny przed lub po. Załóżmy na przykład, że kolumny są rozdzielane tabulatorami:

paste file1.txt file2.txt | cut -f 1,2,3,6

Oto sposób wstępnego filtrowania obu plików, który polega na podstawieniu procesu ksh / bash / zsh.

paste <(<file1.txt sed 's/[[:space:]][[:space:]]*[^[:space:]]*$//') \
      <(<file1.txt sed 's/^[^[:space:]]*[[:space:]][[:space:]]*//')

Awk jest nastawiony przede wszystkim na przetwarzanie jednego pliku na raz, ale możesz zadzwonić, getlineaby czytać z innego pliku równolegle.

awk '
  BEGIN {file2=ARGV[2]; ARGV[2]="";}
  {$0 = $0 ORS getline(); print $1, $2, $3, $6;}
' file1.txt file2.txt

Do tej pory zakładałem, że chcesz dopasować wiersz 1 pliku 1 do wiersza 1 pliku 2, wiersz 2 pliku 1 z wierszem 2 pliku 2 itd. Jeśli chcesz dopasować zawartość kolumny, jest to zupełnie inna sprawa. joinwykona zadanie pod warunkiem, że kolumna, którą chcesz dopasować, jest posortowana.

Gilles „SO- przestań być zły”
źródło