grep между списком объектов

#linux #bash

#linux #bash

Вопрос:

Мне нужно сгенерировать файл ( grep_file.txt ), начиная со списка объектов ( list.txt ) и файла, содержащего некоторые переменные для каждого объекта ( info.txt ). Особенность заключается в том, что в списке файлов объекты могут повторяться, и я хотел бы, чтобы все они были сохранены, без устранения дубликатов, и поэтому каждый имеет в конечном файле свою собственную информацию.

С помощью этого примера я надеюсь сделать все более понятным:

 info.txt: The columns of the file are separeted by "tab"

ABD  cluster1   yes
3d0  cluster2   no
ER5  cluster1   no
T6y  cluster5   yes

list.txt:

ABD
3d0
ER5
T6y
3d0
3d0
ER5
T6y

grep_file.txt:

ABD  cluster1   yes
3d0  cluster2   no
ER5  cluster1   no
T6y  cluster5   yes
3d0  cluster2   no
3d0  cluster2   no
ER5  cluster1   no
T6y  cluster5   yes
  

Я пытался использовать этот скрипт:

 while read p; do
  grep -i "$p" info.txt
done <list.txt > grep_file.txt
  

Но результат таков:

 ABD cluster1    yes
3d0 cluster2    no
ER5 cluster1    yes
T6y cluster5    no
T6y cluster5    no
3d0 cluster2    no
3d0 cluster2    no
ER5 cluster1    yes
T6y cluster5    no
T6y cluster5    no
  

И это неверно, потому что объект T6y появляется в два раза чаще, чем в файле списка.
Может кто-нибудь мне помочь, пожалуйста?

Комментарии:

1. В случае, если вы согласны awk , вы могли бы попробовать подобное awk 'FNR==NR{arr[$1]=$0;next} ($0 in arr){print arr[$0]}' info.txt list.txt .

Ответ №1:

Проблема, с которой вы столкнулись, связана с использованием -i, означающего совпадение без учета регистра

ER5 также будет соответствовать er5 и так

 T6y cluster5    no
  

а также:

 ER5 cluster1    yes
  

Чтобы преодолеть проблему, используйте grep без -i или, если это необходимо, будьте более конкретны в поиске и поэтому используйте:

 grep -Ei "^$p" info.txt
  

Ответ №2:

Вы запускаете подпроцесс «grep» несколько раз, что неэффективно. Не могли бы вы попробовать:

 declare -A hash                         # create an associative array
while IFS= read -r line; do             # read the file line by line
    IFS=$'t' read -r key _ <<< "$line" # split the line on tab
    hash[$key]="$line"                  # store the line with the key
done < "info.txt"

while IFS= read -r key; do              # read the file "list.txt"
    echo "${hash[$key]}"                # print the associated line
done < "list.txt" > "grep_file.txt"
  

Результат:

 ABD     cluster1        yes
3d0     cluster2        no
ER5     cluster1        no
T6y     cluster5        yes
3d0     cluster2        no
3d0     cluster2        no
ER5     cluster1        no
T6y     cluster5        yes