1

The man page for tr(1) says:

       tr - translate or delete characters

SYNOPSIS
       tr [OPTION]... SET1 [SET2]

DESCRIPTION
       Translate, squeeze, and/or delete characters from standard input, writing to standard output.

So as far as I can tell, that means that it takes "\n" and then replaces it with "\n" [which means nothing gets changed].

But that does not explain why doing ls | tr '\n' '\n' has the following effect:

 $ ls 
 Documents   Downloads   Git   Music   Pictures  '#recycle'   Videos
2019-Dec-24 07:28:44 PM modernNeo:modernNeo-debian/home/modernNeo
 $ ls | tr "\n" "\n"
Documents
Downloads
Git
Music
Pictures
#recycle
Videos
modernNeo
  • 175
  • 8
  • 7
    Because `ls` works diferently when feeding a pipe. –  Dec 25 '19 at 03:40
  • can you elaborate please? – modernNeo Dec 25 '19 at 03:41
  • In fact `echo "abcd" | tr "\n" "\n"` -> `abcd` – Paulo Tomé Dec 25 '19 at 03:48
  • 2
    Related: [Output from ls has newlines but displays on a single line. Why?](https://unix.stackexchange.com/questions/10421/output-from-ls-has-newlines-but-displays-on-a-single-line-why) – steeldriver Dec 25 '19 at 03:50
  • 3
    Try `ls | cat`. –  Dec 25 '19 at 03:52
  • 1
    I see now. i thought it was because `tr` was doing something funny but it is `ls` which is behaving oddly. thanks all – modernNeo Dec 25 '19 at 03:58
  • It doesn't matter if the output of `ls` is a pipe or some other kind of file, but if the output is a tty (terminal) or some other kind of file. If you want `ls` to display files in columns even when piped to `tr` or redirected to a regular file, use the `-C` flag: `ls -C | tr '\n' '\n'`. –  Dec 25 '19 at 06:49

1 Answers1

3

The output of the ls utility may differ depending on whether the output is being written directly to a terminal, or to a pipe.

You will get the same behaviour as with tr '\n' \n' if you use cat:

$ ls
file-00 file-01 file-02 file-03 file-04 file-05 file-06 file-07 file-08 file-09
$ ls | cat
file-00
file-01
file-02
file-03
file-04
file-05
file-06
file-07
file-08
file-09

This behaviour, listing one file per line, is the default output of ls described by the POSIX standard for this utility:

The default format shall be to list one entry per line to standard output; the exceptions are to terminals or when one of the -C, -m, or -x options is specified. If the output is to a terminal, the format is implementation-defined.

You will also notice the single quotes around your #recycle filename "disappearing" when the output is filtered through a pipe. In fact, these were never part of the filename, but just the way GNU ls decided to render the name when outputting it to a terminal (based on what characters the name contains; the # is considered "special"). The single quoted name and the output in columns is an "implementation-defined format" permitted by the standard when the output is going to terminal.

Replacing the pipe with a redirection to a file (or to a process substitution in shells that supports these) would also make ls format its output in the "default format", with each filename delimited by a newline character.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936