247
247
Bash: 在变量中迭代行
如何在bash中正确地迭代变量中的行,或者从命令的输出中迭代行?简单地将IFS变量设置为新的行,对于命令的输出是有效的,但是当处理一个包含新行的变量时,就不行。但是,第一个for循环打印出的是单行的所有项目。有什么想法吗?
如何在bash中正确地迭代变量中的行,或者从命令的输出中迭代行?简单地将IFS变量设置为新的行,对于命令的输出是有效的,但是当处理一个包含新行的变量时,就不行。但是,第一个for循环打印出的是单行的所有项目。有什么想法吗?
使用bash,如果你想在一个字符串中嵌入新的行,可以用$''
括起来:
$ list="One\ntwo\nthree\nfour"
$ echo "$list"
One\ntwo\nthree\nfour
$ list=$'One\ntwo\nthree\nfour'
$ echo "$list"
One
two
three
four
如果你已经在一个变量中包含了这样一个字符串,你可以用
while IFS= read -r line; do
echo "... $line ..."
done <<< "$list"
```逐行读取它:
&001
#!/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
下面是一个有趣的for循环的方法:
for item in ${list//\n/
}
do
echo "Item: $item"
done
。它包含了$line
后面的`下面是一个有趣的for循环的方法:
for item in ${list//\n/
}
do
echo "Item: $item"
done
。它包含了$line
后面的的实例。你可以清楚的看到:
cr='
'
for item in ${list//\n/$cr}
do
echo "Item: $item"
done
替换是用空格来代替这些,这就足够让它在循环中工作了:
for item in ${list//\n/ }
do
echo "Item: $item"
done
演示:
$ 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
你也可以先将变量转换为数组,然后迭代。
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
``` &001
这只有在你不想乱用`IFS`和`read`命令的情况下才有用,因为如果你在循环中调用另一个脚本,在返回之前,该脚本可能会清空你的读取缓冲区,就像我遇到的那样。