为什么#"在阅读"使用空参数运行grep时循环停止?

时间:2018-02-16 20:56:15

标签: bash shell

以下代码无法正常工作:

(脚本的最初目的是在两个文件的项目之间建立关系,其中标识符没有以相同的顺序排序,但我的问题引起了对基本shell功能的好奇心)

#!/bin/sh

process_line() {
    id="$1"
    entry=$(grep $id index.txt) # the "grep" line
    if [ "$entry" = "" ]; then
        echo 00000 $id
    else
        echo $entry | awk '{print $2, $1;}'
    fi
}

cat << EOF > index.txt
xyz 33333
abc 11111
def 22222
EOF

cat << EOF | while read line ; do process_line "$line"; done
abc
def

xyz
EOF

输出结果为:

11111 abc
22222 def
00000

但我希望:

11111 abc
22222 def
00000
33333 xyz

(实际输出中缺少最后一行)

我的调查显示&#34; grep&#34; line是导致while循环早期中断的行。但是我看不出因果关系。

2 个答案:

答案 0 :(得分:2)

那是因为在使用空行的第三次迭代中,您使用空id调用process_line。这会导致grep index.txt,即没有文件名。这个grep从stdin读取,并且会消耗你输入while循环的所有输入。

要查看此操作,请在脚本顶部添加set -x

如果使用保证找不到的字符串替换空id,则可以获得所需的行为,例如

entry=$(grep "${id:-NoSuchString}" index.txt)

答案 1 :(得分:1)

更改&#34; process_line&#34;以下功能可能会有所帮助...

process_line() {
        id=$1
        if [ "$id" = "" ]
        then
                echo "00000"
        else
                entry=$(grep "${id}" index.txt)
                echo "$entry" | awk '{ print $2, $1 }'
        fi
}

说明:

  • 如果&#34; id&#34;传入的是空的,然后输出默认的
  • 将grep移动到else子句,因此它仅在&#34; id&#34;时执行。有一个值
  • 解决了grep语句中id周围缺少引号的问题
  • 要考虑的另一件事是&#34; id&#34;不是空的,但在index.txt文件中找不到。这可能导致空白输出。在grep调用之后添加if语句来处理这种情况可能是个好主意,具体取决于整体意图。

希望有所帮助