Разделить строку на два уровня - PullRequest
3 голосов
/ 17 марта 2020

У меня есть следующая строка

my_str="A:Apple|B:Ball|C:Cat"

, и я хочу повторить следующее

A for Apple
B for Ball
C for Cat

Я использую код

IFS="|"
delimiter=':'
my_str="A:Apple|B:Ball|C:Cat"
for pair in ${my_str}; do
  #echo "${pair}"
  s=$pair$delimiter
  var1=${s%%"$delimiter"*}
  var2=${s#*"$delimiter"}
  echo "${var1} for ${var2}"
done

Но вывод Я получаю

A for Apple:
B for Ball:
C for Cat:

Может ли кто-нибудь помочь мне удалить дополнительный разделитель, добавленный в конце?

Ответы [ 4 ]

5 голосов
/ 17 марта 2020

bash s read предоставляет опцию (-d) для настройки разделителя строк, которую можно использовать вместе с IFS.

while IFS=':' read -r -d '|' k v; do
    printf '%s for %s\n' "$k" "$v"
done <<< ${my_str%|}'|'
1 голос
/ 17 марта 2020

1-е решение: Не могли бы вы попробовать следующее.

echo "$my_str" | awk -F'|' '{gsub(/:/," for ");for(i=1;i<=NF;i++){print $i}}'

2-е решение: Использование gsub честное предупреждение, написано и протестировано только с показанными образцами.

echo "$my_str" | awk '{gsub(/:/," for ");gsub(/\|/,"\n")} 1'

Вывод будет следующим.

A for Apple
B for Ball
C for Cat
0 голосов
/ 17 марта 2020

Используйте два вызова для read: один для разделения строки на массив, другой для разделения каждого элемента массива.

my_str="A:Apple|B:Ball|C:Cat"

IFS="|" read -a pairs <<< "$my_str"
for pair in "${my_str[@]}"; do
    IFS=: read letter object <<< "$pair"
    printf '%s for %s\n' "$letter" "$object"
done
0 голосов
/ 17 марта 2020

Использование gnu-awk:

awk -F ':|\n' -v RS='|' '{print $1, "for", $2}' <<< "$my_str"

A for Apple
B for Ball
C for Cat

Для POSIX awk используйте это:

awk -F '[:|]' 'NF%2 == 0{for (i=1; i<=NF; i+=2) print $i, "for", $(i+1)}' <<< "$my_str"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...