2

I have a program which transposes a matrix. It works properly when passed a file as a parameter, but it gives strange output when given input via stdin.

This works:

$ cat m1
1   2   3   4
5   6   7   8

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

This doesn't:

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

This is the code I'm using to transpose the matrix:

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
}

And this code handles the argument passing:

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

I'm aware of this answer but I can't figure out where I've gone wrong. Any ideas?

1 Answer 1

2
for num in $line; do
    cut -f$col $FILE | tr '\n' '\t'
    ((col++))
    echo
done

This loop reads $FILE over and over, once for each column. That works fine for a file but isn't suitable for stdin, which is a stream of data that can only be read once.

A quick fix would be to read the file into memory and use <<< to pass it to read and cut.

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

See An efficient way to transpose a file in Bash for a variety of more efficient one-pass solutions.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.