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

Если у меня есть файл с разделителями, например;

A=1|B=2|C=3|D=4|E=5|F=6

и я хочу извлечь определенные поля и распечатать их в одной строке, используя только стандартные инструменты unix (например, grep, awk, cut). Как я могу это сделать?

Текстовые поля могут не всегда находиться в одном порядке, и может быть больше одной строки, чем на другой. Я хочу иметь возможность выбирать поля на основе их начала.

Таким образом, запрос по указанному выше для A = и C = должен содержать следующую строку в виде одной строки;

A=1 C=2

Благодаря!

1
nl ja de

4 ответы

Я бы рекомендовал использовать awk-версию, которая поддерживает указание RS как регулярное выражение, например. gawk или mawk:

echo 'A=1|B=2|C=3|D=4|E=5|F=6' | 
  awk -v RS='[|\n]' -v ORS=' ' -v pat='(A|C)=' '$0 ~ pat'; echo

Или если вы хотите избежать эха в конце:

echo 'A=1|B=2|C=3|D=4|E=5|F=6' | 
  awk -v RS='[|\n]' -v ORS=' ' -v pat='(A|C)=' '$0 ~ pat; END { printf "\n" }'

Мой любимый:

echo 'A=1|B=2|C=3|D=4|E=5|F=6' | 
  awk '$0 ~ pat' RS='[|\n]' ORS=' ' pat='(A|C)='; echo 

Вывод:

A=1 C=3

редактировать

Bugfix, новые строки также следует рассматривать как разделители записей.

1
добавлено
@ user1977952 Попробуйте с помощью pat = '(A | F) =' и посмотрите, все ли он делает то, что вы хотите, поскольку в этом случае будет добавлена ​​пустая строка. Добавьте {sub (/ \ n /, "")} перед тестом на $ 0 или {sub (/ \ n /, ""); print} после него.
добавлено автор Ed Morton, источник
@EdMorton: Я вижу вашу точку зрения, я обновил ответ на использование regex RS, ограничивая решение gawk или mawk (возможно, другие версии awk?).
добавлено автор Thor, источник
Спасибо, это было именно то, что мне нужно.
добавлено автор user1977952, источник

вы также можете использовать это:

awk -F"|" '{for(i=1;i<=NF;i++){if($i~/[A|C]\=/)printf $i" "}}'

также вы можете использовать perl:

perl -lne 'push @a,/[A|C]=\d+/g;END{print "@a"}'
0
добавлено

использование sed

sed -re 's/(A = [0-9] +) (. *) (C = [0-9] +) (. *)/\ 1 \ 3 /' temp.txt

Вывод

A = 1 C = 3

0
добавлено

это соответствует вашим потребностям?

kent$  echo "A=1|B=2|C=3|D=4|E=5|F=6"|grep -Po "(?<=\||^)(A=|C=)[^|]*"
A=1
C=3

if you want it in single line, pipe it to tr '\n' ' '

0
добавлено
@ user1977952 вы хотите, чтобы его печатали в одной строке, не так ли?
добавлено автор Kent, источник
Привет, к сожалению, это не соответствует 100% моим потребностям, так как он печатает весь вывод на одной строке. Спасибо, в любом случае!
добавлено автор user1977952, источник
Linux Help
Linux Help
2 686 участник(ов)

Правила: https://telegra.ph/Pravila-Linux-Help-10-15

Linux Security
Linux Security
652 участник(ов)

Данная группа принципиально про безопасность и в частности про безопасность Linux. Прочие темы просим обсуждать в профильных чатах.

pro.bash
pro.bash
123 участник(ов)

All about Nix shells, signals, processes and development in general.

Linux Gaming RUS
Linux Gaming RUS
28 участник(ов)

Русскоязычный чатик, посвящённый играм на различных дистрибутивах Linux, а также wine, proton Arch Linux RU @ArchLinuxChatRU Gnome RU @gnome_ru