Как найти совпадающую строку с 1-м столбцом?

Вы должны переопределить скомпилированное значение -для "exec", например,

LS_COLORS="*.py=00;33:fi=00;00:di=01;34:ex=0" export LS_COLORS
2
20.08.2020, 14:55
5 ответов

Осмелюсь предположить, что ваше дело лучше уладить с sed.

Для шаблона match_E2:

$ sed -nE 's/^([^;]+).*(match_E2).*/\1,\2/p' file.txt

Для шаблона pattern_2:

$ sed -nE 's/^([^;]+).*(pattern_2).*/\1,\2/p' file.txt

Для обоих шаблонов за один раз:

$ sed -nE 's/^([^;]+).*(match_E2|pattern_2).*/\1,\2/p' file.txt

То есть в основном:

$ sed -nE 's/^([^;]+).*(    ).*/\1,\2/p' file.txt
#                       ^  ^
#                       |  |
#            ---------------------
# put within these two parentheses the same (Extended Regular Expression) pattern you would use with `grep -E`

Обратите внимание, что он зависит только от того, что по крайней мере один ;является разделителем между первым полем и остальной частью строки.

5
18.03.2021, 23:11

Лучшее, что я могу предложить, это ОЧЕНЬ некрасивый обходной путь:

# Finds first columns
first=(`grep "match_E2" text | awk -F';;' '{print $1}'`)

# Lets join them together now
for column in ${first[@]}; do
  echo "$column,match_E2"
done

Результат:

abcd.corp,match_E2
web1.corp,match_E2
web2.corp,match_E2

Вы также можете создать сценарий или функцию и заменить строку поиска на $1, а затем вызвать ее со строкой поиска в качестве аргумента. Вот так:

Скрипт:

#!/bin/bash
first=(`grep "$1" text | awk -F';;' '{print $1}'`)
for column in ${first[@]}; do
  echo "$column,$1"
done

И тогда вы называете это так:

xxxx@ubuntu:~/test#./script.sh match_E2
abcd.corp,match_E2
web1.corp,match_E2
web2.corp,match_E2
1
18.03.2021, 23:11

Следующая команда awkдолжна делать то, что вы хотите:

awk -F'[;,]' -v pat="match_E2" '$0~pat{for (i=3;i<NF;i++) {if ($i ~ pat) printf("%s,%s\n",$1,$i)}}' file.txt
  • Опция -F'[;,]'указывает awkраспознавать как ;, так и ,как разделитель полей и соответствующим образом разделять строку. Обратите внимание, что, хотя стандарт POSIX предписывает, чтобы такой многосимвольный разделитель полей -интерпретировался как полные регулярные выражения, все же могут существовать awkверсии, которые не реализуют это правильно.

  • Шаблон передается в awk через опцию строки команды -v pat="match_E2"-. Обратите внимание, что это будет интерпретировать шаблон как полное регулярное выражение. Если у вас есть символы, которые имеют особое значение в этом контексте, вам нужно их избежать!

  • Если текущая строка соответствует шаблону($0 ~ patозначает, что «если вся строка соответствует регулярному выражению, хранящемуся где-то в pat» ), он будет перебирать все соответствующие поля (поле 3 является первым полем после последнего;)и определите тот, который действительно соответствует (условию if ($i ~ pat)). Затем он печатает первое поле($1)и соответствующее поле($i)через printf(). Предполагается, что в соответствующей строке может быть только одно такое поле !

Если вы ищете несколько шаблонов, вы можете соответствующим образом сформулировать регулярное выражение в pat, как в

awk -F'[;,]' -v pat="match_E2|pattern_2" '... etc... '

или выполните команду дважды, по одному разу для каждого шаблона.

4
18.03.2021, 23:11

Более grep -oпохожая на awk версия, использующая функцию match:

$ awk -F';' 'match($0,/match_E2|pattern_2/) {print $1 "," substr($0,RSTART,RLENGTH)}' file
abcd.corp,match_E2
web1.corp,match_E2
web2.corp,match_E2
web3.corp,pattern_2
web4.corp,pattern_2
4
18.03.2021, 23:11

Это выполняет полное буквальное сопоставление строк, поэтому оно будет работать, даже если ваши целевые строки содержат метасимволы регулярного выражения или отображаются как подстроки во входных данных:

$ awk '
    BEGIN { strs["match_E2"]; strs["pattern_2"]; FS=";"; OFS="," }
    { for (str in strs) if (index(","$NF",",","str",")) print $1, str }
' file
abcd.corp,match_E2
web1.corp,match_E2
web2.corp,match_E2
web3.corp,pattern_2
web4.corp,pattern_2

В качестве примера частичного и полного сопоставления рассмотрим следующий ввод:

$ cat file
abcd.corp;;a123,Virtual,aws,Linux,Linux,mismatch_E2,Database
web1.corp;;,Virtual,azure,match_E2,Linux,corpo,Database
web2.corp;;match_E2,Virtual,a2responsible,Linux_Suse,Linux,corpo,Database
web3.corp;;Virtual,Virtual,corpo,pattern_275,Linux,corpo,Database
web4.corp;;Virtual,Virtual,corpo,,Linux,pattern_2,Database

Обратите внимание, что теперь первая строка ввода содержит mismatch_E2вместо match_E2, а 4-я строка — pattern_275вместо pattern_2. Теперь запустите на нем приведенный выше awk-скрипт и убедитесь, что он выдает ожидаемый результат :

.
$ awk '
    BEGIN { strs["match_E2"]; strs["pattern_2"]; FS=";"; OFS="," }
    { for (str in strs) if (index(","$NF",",","str",")) print $1, str }
' file
web1.corp,match_E2
web2.corp,match_E2
web4.corp,pattern_2

Для примера сопоставления регулярного выражения и строки измените match_E2в строке 1 на m.*2и patch_2в 4-й строке на p.*2во входных данных:

$ cat file
abcd.corp;;a123,Virtual,aws,Linux,Linux,m.*2,Database
web1.corp;;,Virtual,azure,m.*2,Linux,corpo,Database
web2.corp;;m.*2,Virtual,a2responsible,Linux_Suse,Linux,corpo,Database
web3.corp;;Virtual,Virtual,corpo,pattern_2,Linux,corpo,Database
web4.corp;;Virtual,Virtual,corpo,,Linux,pattern_2,Database

и измените приведенный выше awk-скрипт так, чтобы он искал m.*2и p.*2вместо match_E2и pattern_2, и убедитесь, что он снова выдает ожидаемый результат:

$ awk '
    BEGIN { strs["m.*2"]; strs["p.*2"]; FS=";"; OFS="," }
    { for (str in strs) if (index(","$NF",",","str",")) print $1, str }
' file
abcd.corp,m.*2
web3.corp,p.*2
1
18.03.2021, 23:11

Теги

Похожие вопросы