Сопоставьте строки из двух файлов и полей вывода в определенном порядке - PullRequest
1 голос
/ 23 марта 2019

У меня есть следующие два файла.

query.txt

pumpkin
kiwi

subject.tsv

kiwifruit   something   green
melon   something   red
pumpkinhead something   orange

Я хотел бы просмотреть запрос.txtи проверьте для каждой строки, содержит ли любое первое поле в subject.tsv строку.Если да, к строке добавляется вкладка плюс третье поле из subject.tsv.Порядок строк в query.txt должен быть сохранен в выходных данных.

Я пробовал следующее.

while read query; do echo -e $query"\t"; awk '$1 ~ "$query" {print $3}' subject.tsv; done < query.txt

желаемый вывод:

pumpkin orange
kiwi    green

фактический вывод:

pumpkin
kiwi

Ответы [ 5 ]

2 голосов
/ 23 марта 2019

Bash не выполняет расширение переменной для строки, раскрытой в одинарных кавычках ('), поэтому проблема с вашим скриптом здесь:

'$1 ~ "$query" {print $3}'

Должно быть что-то вроде этого:

'$1 ~ '"$query"' {print $3}'

Но даже после исправления этот скрипт все равно будет неэффективным и подверженным ошибкам. Поэтому я предлагаю вам сделать это за один звонок в awk, например:

awk -F'\t' -v OFS='\t' '
NR==FNR { a[$0] = $3; next } {
    for (b in a) {
        if (index(b, $0)) {
            print $0, a[b]
            break
        }
    }
}' subject.tsv query.txt
1 голос
/ 24 марта 2019

хотя в вопросе пропущено много информации, например, содержит ли файл запроса уникальные строки?или файл темы содержит повторяющиеся строки?но с учетом текущих файлов и требований, пожалуйста, ответьте ниже, и, поскольку он основан на awk, он должен работать и с большими файлами:

awk ' BEGIN{OFS="\t"}
    FILENAME ~ /subject.tsv$/ {
      color[$1]=$3
    }
    FILENAME ~ /query.txt$/ {
      for (i in color) {
      if ( i ~ $1 ) print $1, color[i]
    }
 }'  subject.tsv query.txt

Ниже выводится:

    pumpkin orange
    kiwi    green
0 голосов
/ 25 марта 2019

Вы можете попробовать эту командную строку Perl

$ perl -lane ' BEGIN { open($fh,"query.txt");@q=<$fh>;chomp(@q) } @s=/(\S+)/g; 
    /$q[0]/ and print "$q[0] $s[2]"; if(eof) { close($ARGV); shift @q}; ' subject.tsv subject.tsv

с вашими входами.

$ perl -lane ' BEGIN { open($fh,"query.txt");@q=<$fh>;chomp(@q) } @s=/(\S+)/g; 
     /$q[0]/ and print "$q[0] $s[2]"; if(eof) { close($ARGV); shift @q}; ' subject.tsv subject.tsv

pumpkin orange
kiwi green

$
0 голосов
/ 24 марта 2019

Здесь решение bash

while read pattern; do
    column1=$(cut -d " " -f1 subject.tsv | grep "$pattern")
    allcolumns=$(echo "$pattern $(grep $column1 subject.tsv)")
    echo $allcolumns | cut -d " " -f1,4
done < query.txt

объяснение

Читать все строки query.txt

while read pattern; do
   ...
done < query.txt

Найти шаблон поиска в столбце1

while read pattern; do
   column1=$(cut -d " " -f1 subject.tsv | grep "$pattern") 
   echo $column1
done < query.txt

output

pumpkinhead
kiwifruit

Объединить шаблон из query.txt с совпадениями из subject.tsv

while read pattern; do
    column1=$(cut -d " " -f1 subject.tsv | grep "$pattern")
    allcolumns=$(echo "$pattern $(grep $column1 subject.tsv)")
    echo $allcolumns
done < query.txt

output

pumpkin pumpkinhead something orange
kiwi kiwifruit something green

Извлечьfirst последнее поле слияния

echo $allcolumns | cut -d " " -f1,4

output

pumpkin orange
kiwi green
0 голосов
/ 23 марта 2019

В вашей версии кодов, использующих while, вам нужно передать строку, которую вы хотите найти, в команду awk, используя опцию -v, в противном случае awk будет воспринимать все как простые строки.

Например, если вы хотите передать строку «тыква», содержащуюся в переменной query, вам нужно сделать так:

query="pumpkin"; awk -v query=$query '$1 ~ query' subject.tsv

-v здесь используется для объявления переменной, которая использует содержимое переменной вне awk. Вы можете увидеть объяснение awk

-v var = val
--assign var = val

Присвойте значение val переменной var до начала выполнения программы. Такие значения переменных доступны для правила BEGIN программы AWK.

Таким образом, вы можете попытаться соответственно пересмотреть свои коды, передав свой query в awk.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...