gpt4 book ai didi

linux - 在 shell 脚本的 for 循环中迭代行而不是单词

转载 作者:IT老高 更新时间:2023-10-28 12:40:50 25 4
gpt4 key购买 nike

以下是读取框中所有 DSF 的 shell 脚本。但是由于该行有空格,因此将它们显示在不同的行中。不懂ioscan -m dsf的 friend ,换成ls -ltr,输出就是权限和名字显示在不同的行,但是我希望它们在同一行。

#!/usr/bin/ksh

for a in `ioscan -m dsf`
do
echo $a
done

最佳答案

for 循环并非旨在循环“行”。相反,它会遍历“单词”。

简短术语:“行”是由换行符分隔的内容。 “单词”是由空格(和换行符等)分隔的东西。在 bash 术语中,“单词”被称为“字段”。

循环遍历行的惯用方法是结合使用 while 循环和 read

ioscan -m dsf | while read -r line
do
printf '%s\n' "$line"
done

请注意,由于管道,while 循环位于子shell 中。这可能会导致与变量范围的一些混淆。在 bash 中,您可以使用进程替换来解决此问题。

while read -r line
do
printf '%s\n' "$line"
done < <(ioscan -m dsf)

另见 http://mywiki.wooledge.org/BashFAQ/024


for 循环使用 $IFS 变量中的字符作为分隔符来拆分要循环的内容。 IFS 是内部场分离器的缩写。通常 $IFS 包含一个空格、一个制表符和一个换行符。这意味着 for 循环将遍历“单词”,而不是行。

如果您坚持使用 for 循环来遍历行,则必须将 $IFS 的值更改为仅换行符。但是如果你这样做,你必须保存 $IFS 的旧值并在循环之后恢复它,因为许多其他的东西也依赖于 $IFS

OLDIFS="$IFS"
IFS=$'\n' # bash specific
for line in $(ioscan -m dsf)
do
printf '%s\n' "$line"
done
IFS="$OLDIFS"

在没有 ANSI-C Quoting 的 POSIX shell 中($'\n'),你可以这样做:

IFS='
'

即:在引号之间添加一个实际的新行。

您也可以使用子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

但要注意循环中的命令本身可能依赖于 $IFS 的一些合理设置。然后,您必须在执行命令之前恢复 $IFS 并在下一个循环或类似之前再次设置。我不建议弄乱 $IFS。太多的命令依赖于 $IFS 中一些合理的值,而改变它是一个无休止的噩梦,是寻找晦涩难懂的错误。

另见:

关于linux - 在 shell 脚本的 for 循环中迭代行而不是单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10748703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com