Solusi paling sederhana adalah menggunakan membuat larik args yang dikutip yang kemudian dapat Anda ulangi jika Anda suka atau meneruskan langsung ke perintah.
eval "array=($string)"
for arg in "${array[@]}"; do echo "$arg"; done
hal. Beri komentar jika Anda menemukan cara yang lebih sederhana tanpa eval
.
Sunting:
Membangun jawaban @Hubbitus, kami memiliki versi yang sepenuhnya bersih dan dikutip dengan benar. Catatan:ini berlebihan dan benar-benar akan meninggalkan garis miring terbalik tambahan di bagian kutipan ganda atau tunggal sebelum sebagian besar tanda baca tetapi kebal terhadap serangan.
declare -a "array=($( echo "$string" | sed 's/[][`[email protected]#$%^&*():;<>.,?/\|{}=+-]/\\&/g' ))"
Saya serahkan kepada pembaca yang tertarik untuk memodifikasi sesuai keinginan mereka http://ideone.com/FUTHhj
Ketika saya melihat jawaban David Postill, saya berpikir "pasti ada solusi yang lebih sederhana". Setelah beberapa percobaan saya menemukan karya-karya berikut:-
string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
echo $string
eval 'for word in '$string'; do echo $word; done'
Ini berfungsi karena eval
memperluas baris (menghapus tanda kutip dan memperluas string
) sebelum mengeksekusi baris yang dihasilkan (yang merupakan jawaban sebaris):
for word in "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"; do echo $word; done
Alternatif yang diperluas ke baris yang sama adalah:
eval "for word in $string; do echo \$word; done"
Ini string
diperluas dalam tanda kutip ganda, tetapi $
harus di-escape sehingga word
in tidak diperluas sebelum baris dieksekusi (dalam bentuk lain penggunaan tanda kutip tunggal memiliki efek yang sama). Hasilnya adalah:-
[~/]$ string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
[~/]$ echo $string
"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
[~/]$ eval 'for word in '$string'; do echo $word; done'
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
[~/]$ eval "for word in $string; do echo \$word; done"
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
Bagaimana saya melakukannya?
$ for l in "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"; do echo $l; done
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
Apa yang harus saya lakukan jika string saya ada di bash
variabel?
Pendekatan sederhana menggunakan bash
string tokenizer tidak akan berfungsi, karena terbagi di setiap ruang bukan hanya di luar tanda kutip:
[email protected] /f/test
$ cat ./test.sh
#! /bin/bash
string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
for word in $string; do echo "$word"; done
[email protected] /f/test
$ ./test.sh
"aString
that
may
haveSpaces
IN
IT"
bar
foo
"bamboo"
"bam
boo"
Untuk menyiasatinya, skrip shell berikut (splitstring.sh) menunjukkan satu pendekatan:
#! /bin/bash
string=$(cat <<'EOF'
"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
EOF
)
echo Source String: "$string"
results=()
result=''
inside=''
for (( i=0 ; i<${#string} ; i++ )) ; do
char=${string:i:1}
if [[ $inside ]] ; then
if [[ $char == \\ ]] ; then
if [[ $inside=='"' && ${string:i+1:1} == '"' ]] ; then
let i++
char=$inside
fi
elif [[ $char == $inside ]] ; then
inside=''
fi
else
if [[ $char == ["'"'"'] ]] ; then
inside=$char
elif [[ $char == ' ' ]] ; then
char=''
results+=("$result")
result=''
fi
fi
result+=$char
done
if [[ $inside ]] ; then
echo Error parsing "$result"
exit 1
fi
echo "Output strings:"
for r in "${results[@]}" ; do
echo "$r" | sed "s/\"//g"
done
Keluaran:
$ ./splitstring.sh
Source String: "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
Output strings:
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
Sumber:Jawaban StackOverflow Pisahkan string hanya dengan spasi yang berada di luar tanda kutip oleh choroba. Skrip telah diubah agar sesuai dengan persyaratan pertanyaan.