以下是用于读取框中存在的所有DSF的shell脚本.但由于该行有空格,因此它以不同的行显示.对于那些不理解的人ioscan -m dsf,替换它ls -ltr,然后输出是这样的权限和名称显示在不同的行,但我希望它们在同一行.
#!/usr/bin/ksh
for a in `ioscan -m dsf`
do
echo $a
done
Run Code Online (Sandbox Code Playgroud)
les*_*ana 42
该for循环的目的不是要遍历行.该while循环遍历"字"或"场".
循环线的惯用方法是使用read循环结合$IFS.
ioscan -m dsf | while read -r line
do
printf '%s\n' "$line"
done
Run Code Online (Sandbox Code Playgroud)
请注意,由于管道,while循环位于子shell中.在bash中,您可以通过使用进程替换来解决此问题.
while read -r line
do
printf '%s\n' "$line"
done < <(ioscan -m dsf)
Run Code Online (Sandbox Code Playgroud)
for循环使用$IFS(内部字段分隔符)变量中的字符作为分隔符将值拆分为循环.通常for包含空格,制表符和换行符.这意味着$IFS循环将遍历"单词",而不是循环.
如果您坚持使用for循环遍历行,则必须将值更改$IFS为仅换行.但是如果你这样做,你必须保存旧值$IFS并在循环后恢复它,因为许多其他事情也依赖于$'\n'.
OLDIFS="$IFS"
IFS=$'\n' # bash specific
for line in $(ioscan -m dsf)
do
printf '%s\n' "$line"
done
IFS="$OLDIFS"
Run Code Online (Sandbox Code Playgroud)
在POSIX shell中,没有ANSI-C Quoting($IFS),你可以这样做:
IFS='
'
Run Code Online (Sandbox Code Playgroud)
即:在引号之间添加一个实际的新行.
或者,您可以使用子shell将更改包含到$IFS:
(
# changes to variables in the subshell stay in the subshell
IFS=$'\n'
for line in $(ioscan -m dsf)
do
printf '%s\n' "$line"
done
)
# $IFS is not changed outside of the subshell
Run Code Online (Sandbox Code Playgroud)
也可以看看:
Lri*_*Lri 12
for l in $() 根据IFS执行分词:
$ for l in $(printf %b 'a b\nc'); do echo "$l"; done
a
b
c
$ IFS=$'\n'; for l in $(printf %b 'a b\nc'); do echo "$l"; done
a b
c
Run Code Online (Sandbox Code Playgroud)
如果以后不使用IFS,则不必将其设置为后退.
for l in $() 还执行路径名扩展:
$ printf %b 'a\n*\n' > file.txt
$ IFS=$'\n'
$ for l in $(<file.txt); do echo "$l"; done
a
file.txt
$ set -f; for l in $(<file.txt); do echo "$l"; done; set +f
a
*
Run Code Online (Sandbox Code Playgroud)
如果IFS=$'\n',换行符被剥离并折叠:
$ printf %b '\n\na\n\nb\n\n' > file.txt
$ IFS=$'\n'; for l in $(<file.txt); do echo "$l"; done
a
b
Run Code Online (Sandbox Code Playgroud)
$(cat file.txt)(或$(<file.txt))也将整个文件读入内存.
没有-r反斜杠用于行继续,并在其他字符之前删除:
$ cat file.txt
\1\\2\
3
$ cat file.txt | while read l; do echo "$l"; done
1\23
$ cat file.txt | while read -r l; do echo "$l"; done
\1\\2\
3
Run Code Online (Sandbox Code Playgroud)
IFS中的字符从行的开头和结尾处被删除但未折叠:
$ printf %b '1 2 \n\t3\n' | while read -r l; do echo "$l"; done
1 2
3
$ printf %b ' 1 2 \n\t3\n' | while IFS= read -r l; do echo "$l"; done
1 2
3
Run Code Online (Sandbox Code Playgroud)
如果最后一行没有以换行符结尾,则read为其分配l但是在循环体之前退出:
$ printf 'x\ny' | while read l; do echo $l; done
x
$ printf 'x\ny' | while read l || [[ $l ]]; do echo $l; done
x
y
Run Code Online (Sandbox Code Playgroud)
如果while循环位于管道中,它也在子shell中,因此变量在其外部不可见:
$ x=0; seq 3 | while read l; do let x+=l; done; echo $x
0
$ x=0; while read l; do let x+=l; done < <(seq 3); echo $x
6
$ x=0; x=8 | x=9; echo $x
0
Run Code Online (Sandbox Code Playgroud)