【问题标题】:Unexpected behavior when processing input via stdin but file input works fine通过标准输入处理输入但文件输入工作正常时出现意外行为
【发布时间】:2018-09-28 14:06:18
【问题描述】:

我有一个转置矩阵的程序。将文件作为参数传递时它可以正常工作,但是当通过stdin 给出输入时它会给出奇怪的输出。

这行得通:

$ cat m1
1   2   3   4
5   6   7   8

$ ./matrix transpose m1
1   5   
2   6   
3   7   
4   8

这不是:

$ cat m1 | ./matrix transpose
5
[newline]
[newline]
[newline]

这是我用来转置矩阵的代码:

function transpose {
    # Set file to be argument 1 or stdin 
    FILE="${1:-/dev/stdin}"
    if [[ $# -gt 1 ]]; then
        print_stderr "Too many arguments. Exiting."
        exit 1
    elif ! [[ -r $FILE ]]; then
        print_stderr "File not found. Exiting."
        exit 1
    else
        col=1
        read -r line < $FILE
        for num in $line; do
            cut -f$col $FILE | tr '\n' '\t'
            ((col++))
            echo
        done
        exit 0
    fi
}

这段代码处理参数传递:

# Main
COMMAND=$1
if func_exists $COMMAND; then
    $COMMAND "${@:2}"
else
    print_stderr "Command \"$COMMAND\" not found. Exiting."
    exit 1
fi

我知道this answer,但我不知道我哪里出错了。有什么想法吗?

【问题讨论】:

    标签: bash shell


    【解决方案1】:
    for num in $line; do
        cut -f$col $FILE | tr '\n' '\t'
        ((col++))
        echo
    done
    

    此循环一遍又一遍地读取$FILE,每列一次。这适用于文件,但不适用于标准输入,标准输入是只能读取一次的数据流。

    快速解决方法是将文件读入内存并使用&lt;&lt;&lt; 将其传递给readcut

    matrix=$(< "$FILE")
    read -r line <<< "$matrix"
    for num in $line; do
        cut -f$col <<< "$matrix" | tr '\n' '\t'
        ((col++))
        echo
    done
    

    请参阅An efficient way to transpose a file in Bash,了解各种更高效的一次性解决方案。

    【讨论】:

      猜你喜欢
      • 2015-12-27
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 2020-05-16
      • 2011-12-31
      • 1970-01-01
      • 2012-11-05
      • 1970-01-01
      相关资源
      最近更新 更多