Как напечатать ключи из всех пар ключ-значение - PullRequest
2 голосов
/ 01 октября 2019

Текстовый файл выглядит следующим образом:

key11=val1|key12=val2|key13=val3
key21=val1|key22=val2|key23=val3

Как извлечь ключи, чтобы:

key11|key12|key13
key21|key22|key23

Я попытался безуспешно:

awk '{ gsub(/[^[|]=]+=/,"") }1' file.txt

даетвернуться к фактическим данным:

key11=val1|key12=val2|key13=val3
key21=val1|key22=val2|key23=val3

Ответы [ 5 ]

2 голосов
/ 01 октября 2019

Поскольку вы пометили

while IFS='=|' read -ra words; do
    n=${#words[@]}
    for ((i=1; i<n; i+=2)); do
        unset words[i]
    done
    ( IFS='|'; echo "${words[*]}" )
done < file
1 голос
/ 02 октября 2019
awk -F'[=|]' '{print $1,$3,$5}' OFS="|" file

key11|key12|key13
key21|key22|key23
1 голос
/ 01 октября 2019

Вот одно из решений

echo "key11=val1|key12=val2|key13=val3" \
| awk -F'[=|]' '{
  for (i=1;i<=NF;i+=2){
    printf("%s%s", $i, (i<(NF-1))?"|":"") 
  }
  print""
}'

output

key11|key12|key13

Оно также должно работать, передавая имя файла в качестве аргумента awk, то есть

awk -F'[=|]' '{for (i=1;i<=NF;i+=2){printf("%s%s", $i, (i<(NF-1))?"|":"") }print""}' file1 [file_more_as_will_fit]

Обсуждение

Мы используем многосимвольное значение для FS (FieldSeperator), чтобы каждый символ = и | отмечал начало нового поля.

-F'[=|]'

Поскольку мы знаем, что хотим начать с поля1 для вывода и пропустить все остальные поля, мы используем

for (i=1;i<=NF;i+=2)

printf форматирует вывод, как определено строкой формата '%s%s'. Для области printf формата доступно несколько вариантов, но вам нужно только значение для $i (значение зацикливания, генерирующее ключ) и указание, печатать ли символ | или нет.

printf("%s%s", $i ...)

И мы используем троичный оператор awk, который оценивает, какой номер элемента обрабатывается (i<..). Если это поле не является вторым по последнему, то генерируется символ |.

(i<(NF-1))?"|":"" 

IHTH

1 голос
/ 01 октября 2019

gawk

Это можно сделать с помощью awk, установив FS и OFS:

kent$  awk -F'=[^|]*' -v OFS="" '$1=$1' file
key11|key12|key13
key21|key22|key23

или безопаснее: awk -F.... '{$1=$1}1' file

подстановка (например, sed):

kent$  sed 's/=[^|]*//g' file
key11|key12|key13
key21|key22|key23
1 голос
/ 01 октября 2019

sed

Я сделал это с sed:

sed -r 's/([[:alnum:]]*)=[[:alnum:]]*/\1/g' < file.txt

, проверенным здесь, и получил:

key11|key12|key13
key21|key22|key23

s/<pattern>/<subst>/ означает "заменить <pattern>на <subst> ", и с g в конце он сделает это для каждого шаблона, найденного в строке.

[[:alnum:]]* эквивалентен [0-9a-zA-Z]* и означает любое количество буквили цифры.

Первый шаблон между парентезом будет соответствовать \1 в замене, второй \2 и так далее.

Таким образом, он будет соответствовать каждому «ключу = значению» и заменять его «ключом».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...