What is the magic separator between filenames in ls output?

Or does it know when its output is being piped to another command, and format its output differently in this case?

Yes. From the full manual (available through info ls if the documentation is installed):

If standard output is a terminal, the output is in columns (sorted vertically) and control characters are output as question marks; otherwise, the output is listed one per line and control characters are output as-is.

If you like the one column output, you can run

ls -1

to get it in the terminal as well.


ls detects it when you pipe its output. You can see it in the documentation:

If standard output is a terminal, the output is in columns (sorted vertically) and control characters are output as question marks; otherwise, the output is listed one per line and control characters are output as-is.

If you want each file in the output to be placed on a separate line regardless of the pipe redirection, you can use

ls -1