Разбиение строки в массив - PullRequest
7 голосов
/ 24 октября 2009

Я хочу разбить строку и построить массив. Я попробовал следующий код:

myString="first column:second column:third column"
set -A myArray `echo $myString | awk 'BEGIN{FS=":"}{for (i=1; i<=NF; i++) print $i}'`
# Following is just to make sure that array is constructed properly
i=0
while [ $i -lt ${#myArray[@]} ]
do
echo "Element $i:${myArray[$i]}"
(( i=i+1 ))
done
exit 0

It produces the following result:
Element 0:first
Element 1:column
Element 2:second
Element 3:column
Element 4:third
Element 5:column

This is not what I want it to be. When I construct the array, I want that array to contain only three elements.
Element 0:first column
Element 1:second column
Element 2:third column

Не могли бы вы посоветовать?

Ответы [ 5 ]

15 голосов
/ 25 октября 2009

Вот как я мог бы подойти к этой проблеме: используйте переменную IFS, чтобы указать оболочке (bash), что вы хотите разбить строку на токены, разделенные двоеточиями.

$ cat split.sh
#!/bin/sh

# Script to split fields into tokens

# Here is the string where tokens separated by colons
s="first column:second column:third column"

IFS=":"     # Set the field separator
set $s      # Breaks the string into $1, $2, ...
i=0
for item    # A for loop by default loop through $1, $2, ...
do
    echo "Element $i: $item"
    ((i++))
done

Запустите его:

$ ./split.sh
Element 0: first column
Element 1: second column
Element 2: third column
5 голосов
/ 24 октября 2009

если вы определенно хотите использовать массивы в Bash, попробуйте этот способ

$ myString="first column:second column:third column"
$ myString="${myString//:/ }" #remove all the colons
$ echo "${myString}"
first column second column third column
$ read -a myArr <<<$myString
$ echo ${myArr[@]}
first column second column third column
$ echo ${myArr[1]}
column
$ echo ${myArr[2]}
second

в противном случае «лучший» метод - использовать awk целиком

4 голосов
/ 07 апреля 2011

Обратите внимание, что сохранение и восстановление IFS, как я часто видел в этих решениях, имеет побочный эффект: если IFS не был установлен, он в конечном итоге изменится на пустую строку, что вызывает странные проблемы с последующим разбиением.

Вот решение, которое я придумала на основе * * Антона Олсена, расширенного для обработки> 2 значений, разделенных двоеточием. Он обрабатывает значения в списке, которые имеют пробелы правильно, без разделения на пробелы.

colon_list=${1}  # colon-separate list to split
while true ; do
    part=${colon_list%%:*}  # Delete longest substring match from back
    colon_list=${colon_list#*:}  # Delete shortest substring match from front
    parts[i++]=$part
    # We are done when there is no more colon
    if test "$colon_list" = "$part" ; then
        break
    fi
done
# Show we've split the list
for part in "${parts[@]}"; do
    echo $part
done
3 голосов
/ 13 декабря 2012

Кш или Баш

#! /bin/sh
myString="first column:second column:third column"
IFS=: A=( $myString )

echo ${A[0]}
echo ${A[1]}
2 голосов
/ 24 октября 2009

Похоже, вы уже нашли решение, но учтите, что вы можете полностью отказаться от awk:

myString="first column:second column:third column"
OIFS="$IFS"
IFS=':'
myArray=($myString)
IFS=$OIFS
i=0
while [ $i -lt ${#myArray[@]} ]
do
    echo "Element $i:${myArray[$i]}"
    (( i=i+1 ))
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...