如何在 bash 中的变量或命令输出中正确迭代行?简单地将 IFS 变量设置为新行适用于命令的输出,但不适用于处理包含新行的变量。
例如
#!/bin/bash
list="One\ntwo\nthree\nfour"
#Print the list with echo
echo -e "echo: \n$list"
#Set the field separator to new line
IFS=$'\n'
#Try to iterate over each line
echo "For loop:"
for item in $list
do
echo "Item: $item"
done
#Output the variable to a file
echo -e $list > list.txt
#Try to iterate over each line from the cat command
echo "For loop over command output:"
for item in `cat list.txt`
do
echo "Item: $item"
done
Run Code Online (Sandbox Code Playgroud)
这给出了输出:
echo:
One
two
three
four
For loop:
Item: One\ntwo\nthree\nfour
For loop over command output:
Item: One
Item: two
Item: three
Item: four
Run Code Online (Sandbox Code Playgroud)
如您所见,回显变量或迭代cat
命令会正确地一一打印每一行。但是,第一个 for 循环将所有项目打印在一行上。有任何想法吗?
gle*_*man 370
使用 bash,如果您想在字符串中嵌入换行符,请使用以下内容将字符串括起来$''
:
$ list="One\ntwo\nthree\nfour"
$ echo "$list"
One\ntwo\nthree\nfour
$ list=$'One\ntwo\nthree\nfour'
$ echo "$list"
One
two
three
four
Run Code Online (Sandbox Code Playgroud)
如果变量中已经有这样的字符串,则可以使用以下命令逐行读取:
while IFS= read -r line; do
echo "... $line ..."
done <<< "$list"
Run Code Online (Sandbox Code Playgroud)
max*_*ost 105
您可以使用while
+ read
:
some_command | while read line ; do
echo === $line ===
done
Run Code Online (Sandbox Code Playgroud)
顺便提一句。该-e
选项echo
是非标准的。printf
如果您想要便携性,请改用。
小智 49
#!/bin/sh
items="
one two three four
hello world
this should work just fine
"
IFS='
'
count=0
for item in $items
do
count=$((count+1))
echo $count $item
done
Run Code Online (Sandbox Code Playgroud)
Mat*_*Mat 22
这是执行 for 循环的一种有趣方式:
for item in ${list//\\n/
}
do
echo "Item: $item"
done
Run Code Online (Sandbox Code Playgroud)
更明智/可读的将是:
cr='
'
for item in ${list//\\n/$cr}
do
echo "Item: $item"
done
Run Code Online (Sandbox Code Playgroud)
但这太复杂了,你只需要一个空间:
for item in ${list//\\n/ }
do
echo "Item: $item"
done
Run Code Online (Sandbox Code Playgroud)
您的$line
变量不包含换行符。它包含\
后跟 的
实例n
。你可以清楚地看到:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo $list | hexdump -C
$ ./t.sh
00000000 4f 6e 65 5c 6e 74 77 6f 5c 6e 74 68 72 65 65 5c |One\ntwo\nthree\|
00000010 6e 66 6f 75 72 0a |nfour.|
00000016
Run Code Online (Sandbox Code Playgroud)
替换是用空格替换那些,这足以让它在 for 循环中工作:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo ${list//\\n/ } | hexdump -C
$ ./t.sh
00000000 4f 6e 65 20 74 77 6f 20 74 68 72 65 65 20 66 6f |One two three fo|
00000010 75 72 0a |ur.|
00000013
Run Code Online (Sandbox Code Playgroud)
演示:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo ${list//\\n/ } | hexdump -C
for item in ${list//\\n/ } ; do
echo $item
done
$ ./t.sh
00000000 4f 6e 65 20 74 77 6f 20 74 68 72 65 65 20 66 6f |One two three fo|
00000010 75 72 0a |ur.|
00000013
One
two
three
four
Run Code Online (Sandbox Code Playgroud)
您也可以先将变量转换为数组,然后对其进行迭代。
lines="abc
def
ghi"
declare -a theArray
while read -r line
do
theArray+=("$line")
done <<< "$lines"
for line in "${theArray[@]}"
do
echo "$line"
#Do something complex here that would break your read loop
done
Run Code Online (Sandbox Code Playgroud)
这仅在您不想弄乱命令IFS
并且也有问题时有用read
,因为它可能发生,如果您在循环中调用另一个脚本,该脚本可以在返回之前清空读取缓冲区,就像我发生的那样.
归档时间: |
|
查看次数: |
372122 次 |
最近记录: |