文件输入在while循环中消耗

时间:2016-07-30 01:40:00

标签: bash while-loop

我正在阅读查找文件并为文件中的每一行执行一组操作。但是while循环只读取文件中的第一行并退出。这是我当前的代码。

sql_from_lkp $lookup

function sql_from_lkp {
    lkp=$1
    while read line; do
        sql_from_columns ${line}
        echo ${line}
    done < ${lkp}
}

function sql_from_columns {
    table_name=$1
    table_column_info_file=${table_name}_columns
    line_count=`cat $table_info_file | wc -l`
    ....
}

通过有选择地评论代码,我发现如果我评论line_count行,while循环遍历文件中的每一行并且工作正常。因此输入被cat语句消耗。

我已经检查了其他答案,并了解ssh通常使用while循环内的文件输入,如果未使用-n选项。但不知道如何解决这个问题。需要一些帮助。

1 个答案:

答案 0 :(得分:3)

您错误输入了变量名称:$table_info_file应为$table_column_info_file

如果你纠正了,你的问题就会消失。

通过引用一个非现存的变量 - 错误的$table_info_file - 您在cat | wc -l中基本上执行cat(没有传递给sql_from_columns()的文件名参数) ,使cat stdin 读取。

因此 - 在while循环中读取 1st 行后,cat中的sql_from_columns()命令消耗整个 >输入的输入(< ${lkp}),这就是第一次迭代后while循环退出的原因。

一般来说,

  • 您应该引用所有变量引用,以免将其值置于word-splitting and globbing

  • Bash不允许您在功能被定义之前调用它们,因此如您的问题所示,您的代码从根本上无法正常工作。< / p>

  • 虽然仍然支持命令替换的旧`...`语法,但它有pitfalls that can be avoided with the modern $(...) syntax

  • 更有效的计算行数的方法是通过wc -l而不是通过<将输入文件传递到cat,并且管道(wc也接受文件名操作数直接,但它会在计数后打印输入文件名。

    • 顺便提一下,如果你这样做,你可能会更容易找到错误的变量引用,因为在ambiguous redirect之后没有文件名时Bash会报告<错误。

这是一个解决所有问题的重新制定:

function sql_from_lkp {
    lkp=$1
    while read line; do
        sql_from_columns "${line}"
        echo "${line}"
    done < "${lkp}"
}

function sql_from_columns {
    table_name=$1
    table_column_info_file=${table_name}_columns
    line_count=$(wc -l < "$table_column_info_file")
    # ...
}

sql_from_lkp "$lookup"

请注意,我只添加了双引号,严格要求使命令健壮;每当引用参数(变量)时添加它们都不会有害。