如何在 shell 中逐行处理命令的输出?

问题描述 投票:0回答:8

我需要从 bash 脚本处理库的共享库依赖项。

for
命令逐字处理:

for DEPENDENCY in `otool -L MyApplication | sed 1d`
do
    ...
done

如何逐行处理结果?

shell
8个回答
41
投票

您应该使用

read
命令。

otool -L MyApplication | sed 1d | \
while read i
do
  echo "line: " $i
done

请参阅 bashref 了解 read 内置函数及其选项的描述。您还可以查看以下教程,了解将

read
for
结合使用的示例。


10
投票
otool -L MyApplication | sed 1d | while read line ;
do
  # do stuff with $line
done

3
投票

尝试将内部字段分隔符更改为换行符。默认情况下,bash 在使用 for 循环时将用空格分隔标记。您的 IFS 设置将使 for 循环根据 IFS 等于的任何字符串来拆分标记(从而通过换行符而不是通过空格来拆分列表标记)。

[bash ] $ IFS="
"
[bash ] $ for DEPENDENCY in `otool -L MyApplication | sed 1d`
do
    ....
done

2
投票

您必须使用 shell 内置功能

read
,但要小心包含空格和制表符的行。我建议本地更改
$IFS
的值:

 otool -L MyApplication | sed 1d | \
 while IFS= read i; do
     echo "line: $i"
 done

[编辑:应用了查尔斯的建议]


1
投票

您可以使用

awk
按行处理内容。到底什么是最好的方法取决于您想要做什么。


1
投票

你也可以用 awk 来做。无需使用 bash for 循环

otool -L MyApplication | awk 'NR>1
{
  # do your stuff here since awk process line by line.
}' 

1
投票

现代 bash 方式:

while read i; do
    ...
done < <(otool -L MyApplication | sed 1d)

注意:两个“<"s above is not a typo, that's the correct syntax.


0
投票

我喜欢寻找替代的做事方式,所以这是另一种创造性的方式,使用文件描述符和 exec 在后台执行。这可能不是最佳实践,甚至不是最有效的,但我认为这可能对某些人有用。

exec 3< <(otool -L MyApplication | sed 1d)
while IFS= read -r <&3 line; do
     echo "line: $line"
 done

常见的做法似乎使用文件描述符(fd)3,但您可以使用其他数字,甚至变量。请记住 fd 0、1 和 2 分别是 stdin、stdout 和 stderr。

在此处阅读有关重定向的信息:bash 手册

© www.soinside.com 2019 - 2024. All rights reserved.