Как напечатать обязательные поля - PullRequest
0 голосов
/ 21 декабря 2018

Строки ввода:

a b=34 c d="12 34 54" e f=387
a b=12 c z d="89 08 23" e f=321 g=12

Я хочу напечатать два поля b и d.
Требуется Ouptut, как:

b=34 d="12 34 54"
b=12 d="89 08 23"

Я пробовал как

awk '{print $2, $4}' filename

но это не дает правильного вывода.

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Awk из коробки не анализирует указанные поля.Если вы хотите извлечь поля в кавычках с помощью Awk, вам нужно реализовать синтаксический анализ полей в кавычках.

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

Если вы можете доверять вводу (т. е. он поступает из файла конфигурации, которым вы полностью управляете), тогда что-то вроде

string='a b=34 c d="12 34 54" e f=387'
eval "$string"

установит все переменные в их ожидаемые значения.

Возможно, вы захотите разобрать строку самостоятельно.Попробуйте это:

grepvar () {
    grep -Po "$1"'=\K([^"]+|"[^"]*")'
}
a=$(grepvar "a" filename)
b=$(grepvar "b" <<<"$string")

Если у вас нет grep -P (который является расширением GNU), есть простые обходные пути;но вы не очень много нам рассказываете о своих требованиях, и есть много почти дубликатов этого вопроса, поэтому не составит труда найти что-то подходящее для вас.

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

grep -Eo 'a=([^"]+|"[^"]*")' filename
grep -Eo 'b=([^"]+|"[^"]*")' <<<"$string"

Выше показано, как читать из файла с именем filename и как анализировать переменную $string, которая уже содержит текст.<<< «здесь строка» является расширением Bash, которое не будет работать, например, с sh.

0 голосов
/ 21 декабря 2018

Если доступно gawk 4.0 или новее, как насчет использования FPAT?
Пожалуйста, попробуйте:

gawk -v FPAT='[^ ]+|\\w+="[^"]+"' '
    {for (i=1; i<=NF; i++) if (match($i, "^(b|d)")) printf("%s ", $i); print ""}
' input.txt

Вывод:

b=34 d="12 34 54" 
b=12 d="89 08 23" 

FPATпеременная awk - это регулярное выражение, которое соответствует содержимому каждого поля, а не разделяет строку разделителем полей.

0 голосов
/ 21 декабря 2018

Это sed должно работать здесь:

sed -E -n 's/[^b]*(b=[0-9]+) [^d]*(d=".*") [^bd]*/\1 \2/p' file_name

Вывод:

b=34 d="12 34 54"
b=12 d="89 08 23"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...