Вы должны переопределить скомпилированное значение -для "exec", например,
LS_COLORS="*.py=00;33:fi=00;00:di=01;34:ex=0" export LS_COLORS
Осмелюсь предположить, что ваше дело лучше уладить с 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`
Обратите внимание, что он зависит только от того, что по крайней мере один ;
является разделителем между первым полем и остальной частью строки.
Лучшее, что я могу предложить, это ОЧЕНЬ некрасивый обходной путь:
# 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
Следующая команда 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... '
или выполните команду дважды, по одному разу для каждого шаблона.
Более 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
Это выполняет полное буквальное сопоставление строк, поэтому оно будет работать, даже если ваши целевые строки содержат метасимволы регулярного выражения или отображаются как подстроки во входных данных:
$ 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