Как разделить строку на разделитель в Bash? - PullRequest
1755 голосов
/ 28 мая 2009

Эта строка хранится в переменной:

IN="bla@some.com;john@home.com"

Теперь я хотел бы разделить строки на ; разделитель так, чтобы у меня было:

ADDR1="bla@some.com"
ADDR2="john@home.com"

Мне не обязательно нужны переменные ADDR1 и ADDR2. Если они являются элементами массива, это даже лучше.


После предложений из приведенных ниже ответов я получил следующее:

#!/usr/bin/env bash

IN="bla@some.com;john@home.com"

mails=$(echo $IN | tr ";" "\n")

for addr in $mails
do
    echo "> [$addr]"
done

Выход:

> [bla@some.com]
> [john@home.com]

Было решение, включающее установку Internal_field_separator (IFS) на ;. Я не уверен, что случилось с этим ответом. Как восстановить IFS назад по умолчанию?

RE: IFS решение, я попробовал это, и оно работает, я сохраняю старый IFS и затем восстанавливаю его:

IN="bla@some.com;john@home.com"

OIFS=$IFS
IFS=';'
mails2=$IN
for x in $mails2
do
    echo "> [$x]"
done

IFS=$OIFS

Кстати, когда я пытался

mails2=($IN)

Я получил только первую строку при печати в цикле, без скобок вокруг $IN это работает.

Ответы [ 34 ]

0 голосов
/ 13 июня 2018

Еще один поздний ответ ... Если вы склонны к Java, вот решение bashj (https://sourceforge.net/projects/bashj/):

#!/usr/bin/bashj

#!java

private static String[] cuts;
private static int cnt=0;
public static void split(String words,String regexp) {cuts=words.split(regexp);}
public static String next() {return(cnt<cuts.length ? cuts[cnt++] : "null");}

#!bash

IN="bla@some.com;john@home.com"

: j.split($IN,";")    # java method call

while true
do
    NAME=j.next()     # java method call
    if [ $NAME != null ] ; then echo $NAME ; else exit ; fi
done
0 голосов
/ 12 октября 2011

Существует два простых метода:

cat "text1;text2;text3" | tr " " "\n"

и

cat "text1;text2;text3" | sed -e 's/ /\n/g'
0 голосов
/ 26 февраля 2016

Возможно, не самое элегантное решение, но работает с * и пробелами:

IN="bla@so me.com;*;john@home.com"
for i in `delims=${IN//[^;]}; seq 1 $((${#delims} + 1))`
do
   echo "> [`echo $IN | cut -d';' -f$i`]"
done

Выходы

> [bla@so me.com]
> [*]
> [john@home.com]

Другой пример (разделители в начале и в конце):

IN=";bla@so me.com;*;john@home.com;"
> []
> [bla@so me.com]
> [*]
> [john@home.com]
> []

По сути, он удаляет все символы, кроме ;, что делает delims например. ;;;. Затем он выполняет цикл for от 1 до number-of-delimiters, что считается ${#delims}. Последний шаг - безопасно получить $i часть, используя cut.

.
0 голосов
/ 14 июня 2012

Однострочник для разделения строки, разделенной ';' в массив это:

IN="bla@some.com;john@home.com"
ADDRS=( $(IFS=";" echo "$IN") )
echo ${ADDRS[0]}
echo ${ADDRS[1]}

Это только устанавливает IFS в подоболочке, поэтому вам не нужно беспокоиться о сохранении и восстановлении его значения.

...