2

The first command below produces each number on a separate line, and I would expect the second command to do the same thing because the only difference between the two is that we are using echo '1 2 3' and echo {1..3} (both of which produce the same output). But, the second command produces the numbers that are separated by tabs instead of new lines. Why?

Furthermore, notice that the only difference between the second and the third commands is that we are passing the result to paste via process substitution, but without that, it shows the expected result, which could imply that it is a paste related issue, but I don't quite see what the issue is.

§ paste <(echo '1 2 3' | tr ' ' '\t' | tr '\t' '\n') 1 2 3 § paste <(echo {1..3} | tr ' ' '\t' | tr '\t' '\n') 1 2 3 § echo {1..3} | tr ' ' '\t' | tr '\t' '\n' 1 2 3 

I tried to see the output produced at the end of the process substitution pipeline to see what was being output, and it does indeed appear to be the same.

§ paste <(echo {1..3} | tr ' ' '\t' | tr '\t' '\n' | tee /dev/stderr) > /dev/null 1 2 3 § paste <(echo '1 2 3' | tr ' ' '\t' | tr '\t' '\n' | tee /dev/stderr) > /dev/null 1 2 3 

If it matters, here are the versions of the tools:

§ which tr paste /usr/local/opt/coreutils/libexec/gnubin/tr /usr/local/opt/coreutils/libexec/gnubin/paste 
§ tr --version tr (GNU coreutils) 9.1 Copyright (C) 2022 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. Written by Jim Meyering. 
§ paste --version paste (GNU coreutils) 9.1 Copyright (C) 2022 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. Written by David M. Ihnat and David MacKenzie. 
§ bash --version bash --version GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20) Copyright (C) 2007 Free Software Foundation, Inc. 
§ sw_vers ProductName: macOS ProductVersion: 11.7.10 BuildVersion: 20G1427 

I am on macOS, but use GNU utils installed via brew.


Addition debug information requested by comments with set -x active:

§ paste <(echo {1..3} | tr ' ' '\t' | tr '\t' '\n') + paste /dev/fd/63 /dev/fd/62 /dev/fd/61 ++ echo 1 ++ echo 3 ++ tr ' ' '\t' ++ tr ' ' '\t' ++ tr '\t' '\n' ++ tr '\t' '\n' ++ echo 2 ++ tr ' ' '\t' ++ tr '\t' '\n' 1 2 3 
§ paste <(echo {1..3} | tr ' ' '\n') + paste /dev/fd/63 /dev/fd/62 /dev/fd/61 ++ echo 1 ++ tr ' ' '\n' ++ echo 2 ++ echo 3 ++ tr ' ' '\n' ++ tr ' ' '\n' 1 2 3 
§ echo {1..3} | tr ' ' '\n' | paste + tr ' ' '\n' + echo 1 2 3 + paste 1 2 3 

And hexdump output:

§ paste <(echo {1..3} | tr ' ' '\n') | hexdump -C 00000000 31 09 32 09 33 0a |1.2.3.| 00000006 
§ echo {1..3} | tr ' ' '\n' | paste | hexdump -C 00000000 31 0a 32 0a 33 0a |1.2.3.| 00000006 
7
  • Using single quotes inhibits special character interpretation. Instead, use "\t" and "\n". Commented Nov 3, 2023 at 2:19
  • @waltinator - I am not sure, I follow. The first example clearly shows that tr is able to interpret the special characters. I do not intend for the shell to do the interpolation, but even with double quotes, it makes no difference, i.e., paste <(echo {1..3} | tr " " "\t" | tr "\t" "\n") produces a tab-separated list like the second command. Commented Nov 3, 2023 at 3:25
  • @waltinator -If it helps, echo {1..3} | tr ' ' '\t' | tr '\t' '\n' | paste produces the correct output too. So, piping to paste works fine, but using paste with process substitution seemingly interprets the lines as columns (?). But, why? Commented Nov 3, 2023 at 3:49
  • 5
    Ignore waltinator’s comment, it’s not relevant here. FWIW I get the expected behaviour with {1..3} but I’m not using macOS. Commented Nov 3, 2023 at 7:11
  • @waltinator no they don't. The shell doesn't interpret '\t' and "\t" differently, both just mean a literal \ followed by a literal t. You would need $'\t' for the shell to interpret that as a tab. For tr, single and double quotes make no difference. Compare echo {1..3} | tr ' ' '\t' with echo {1..3} | tr ' ' \\t or echo {1..3} | tr ' ' "\t" and you will see all three produce the same output. Commented Nov 3, 2023 at 9:38

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.