вывод всех значений столбцов после точного совпадения переменных в файле

#linux #bash #shell #awk #sh

#linux #bash #оболочка #awk #sh

Вопрос:

У меня есть файл list.txt содержащий такие данные, как этот

 hvar-mp-log.hvams europe@gmail.com asia@gmail.com aust@gmail.com
mvar-mp-log.mvams japan@gmail.com ant@gmail.com
mst-mp-log.mst  korea@gmail.com maxwell@gmil.com antra@gamil.com
pif-mp-log-pif atlas@gmail.com  korea@gamil.com japan@gmail.com mexco@gmail.com
 

Мне нужно сопоставить строку в list.txt и выведите соответствующие данные столбца string.

Если строка=mst-mp-log.mst print korea@gmail.com maxwell@gmil.com antra@gamil.com

Я могу сопоставить string=mst-mp-log.mst, как в этом примере, дает мне только информацию о втором столбце, например korea@gmail.com

 string="mst-mp-log.mst"
awk -v var="$string" '$1 == var {print $2}' list.txt
 

как распечатать совпадающую строку со всеми идентификаторами почты. ожидаемый результат должен быть следующим
korea@gmail.com maxwell@gmil.com antra@gamil.com

Ответ №1:

 $ awk -v tgt='mst-mp-log.mst' '$1==tgt{$1=""; $0=$0; $1=$1; print}' file
korea@gmail.com maxwell@gmil.com antra@gamil.com
 

Объяснение:

  • $1==tgt — очевидно
  • $1="" — устанавливает исходное значение $ 1 равным нулю и восстанавливает значение $ 0, но $ 1 по-прежнему является полем (только теперь с нулевым значением), поэтому оно все еще существует в записи, и поэтому между $ 1 и $ 2 находится пробел (OFS), как и между всеми полями.
  • $0=$0 — повторно разбивает запись на новые номера полей, поэтому исходный $ 1 удаляется, а $ 2 становится новым $ 1, но не изменяет фактическую строку, составляющую запись, поэтому пробел все еще существует в ее начале
  • $1=$1 — принудительно восстанавливает значение $ 0 из его полей и, таким образом, удаляет начальный пробел
  • print — очевидно

Здесь вы можете пошагово увидеть, что происходит с записью и полями:

 awk -v tgt='mst-mp-log.mst' '$1==tgt {
    printf "nRecord original:n<%s>n", $0 ; for (i=1; i<=NF; i  ) printf "tField %d/%d [%s]n", i, NF, $i

    $1=""
    printf "nRecord after $1="":n<%s>n", $0 ; for (i=1; i<=NF; i  ) printf "tField %d/%d [%s]n", i, NF, $i

    $0=$0
    printf "nRecord after $0=$0:n<%s>n", $0 ; for (i=1; i<=NF; i  ) printf "tField %d/%d [%s]n", i, NF, $i

    $1=$1
    printf "nRecord after $1=$1:n<%s>n", $0 ; for (i=1; i<=NF; i  ) printf "tField %d/%d [%s]n", i, NF, $i
    print ""

    print
}' file
 
 Record original:
<mst-mp-log.mst  korea@gmail.com maxwell@gmil.com antra@gamil.com>
        Field 1/4 [mst-mp-log.mst]
        Field 2/4 [korea@gmail.com]
        Field 3/4 [maxwell@gmil.com]
        Field 4/4 [antra@gamil.com]

Record after $1="":
< korea@gmail.com maxwell@gmil.com antra@gamil.com>
        Field 1/4 []
        Field 2/4 [korea@gmail.com]
        Field 3/4 [maxwell@gmil.com]
        Field 4/4 [antra@gamil.com]

Record after $0=$0:
< korea@gmail.com maxwell@gmil.com antra@gamil.com>
        Field 1/3 [korea@gmail.com]
        Field 2/3 [maxwell@gmil.com]
        Field 3/3 [antra@gamil.com]

Record after $1=$1:
<korea@gmail.com maxwell@gmil.com antra@gamil.com>
        Field 1/3 [korea@gmail.com]
        Field 2/3 [maxwell@gmil.com]
        Field 3/3 [antra@gamil.com]

korea@gmail.com maxwell@gmil.com antra@gamil.com
 

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

1. Спасибо Эду Мортону за подробное объяснение решения.

Ответ №2:

Альтернативное решение без использования awk

 # Capture the search output into bash array
array=( $(grep "$string" list.txt) )

# First column (Index-0) is your search string, remaining are the email IDs, so print array elements starting from Index 1
echo ${array[@]:1}
korea@gmail.com maxwell@gmil.com antra@gamil.com

# Print all array elements separated by space
echo ${array[@]}
mst-mp-log.mst korea@gmail.com maxwell@gmil.com antra@gamil.com

# Find number of elements in array
echo ${#array[@]}
4

# Advantage with this solution is that you can iterate over the array using a for loop:
for str in "${array[@]}"; do
   echo $str
done
mst-mp-log.mst
korea@gmail.com
maxwell@gmil.com
antra@gamil.com
 

Это может потребовать небольшой корректировки, если структура файла изменится