How do I list one filename per output line in Linux?
I'm using ls -a
command to 开发者_运维百科get the file names in a directory, but the output is in a single line.
Like this:
. .. .bash_history .ssh updater_error_log.txt
I need a built-in alternative to get filenames, each on a new line, like this:
.
..
.bash_history
.ssh
updater_error_log.txt
Use the -1
option (note this is a "one" digit, not a lowercase letter "L"), like this:
ls -1a
First, though, make sure your ls
supports -1
. GNU coreutils (installed on standard Linux systems) and Solaris do; but if in doubt, use man ls
or ls --help
or check the documentation. E.g.:
$ man ls
...
-1 list one file per line. Avoid '\n' with -q or -b
Yes, you can easily make ls
output one filename per line:
ls -a | cat
Explanation: The command ls
senses if the output is to a terminal or to a file or pipe and adjusts accordingly.
So, if you pipe ls -a
to python it should work without any special measures.
Ls is designed for human consumption, and you should not parse its output.
In shell scripts, there are a few cases where parsing the output of ls does work is the simplest way of achieving the desired effect. Since ls might mangle non-ASCII and control characters in file names, these cases are a subset of those that do not require obtaining a file name from ls
.
In python, there is absolutely no reason to invoke ls
. Python has all of ls
's functionality built-in. Use os.listdir
to list the contents of a directory and os.stat
or os
to obtain file metadata. Other functions in the os
modules are likely to be relevant to your problem as well.
If you're accessing remote files over ssh, a reasonably robust way of listing file names is through sftp:
echo ls -1 | sftp remote-site:dir
This prints one file name per line, and unlike the ls
utility, sftp
does not mangle nonprintable characters. You will still not be able to reliably list directories where a file name contains a newline, but that's rarely done (remember this as a potential security issue, not a usability issue).
In python (beware that shell metacharacters must be escapes in remote_dir
):
command_line = "echo ls -1 | sftp " + remote_site + ":" + remote_dir
remote_files = os.popen(command_line).read().split("\n")
For more complex interactions, look up sftp's batch mode in the documentation.
On some systems (Linux, Mac OS X, perhaps some other unices, but definitely not Windows), a different approach is to mount a remote filesystem through ssh with sshfs, and then work locally.
you can use ls -1
ls -l
will also do the work
You can also use ls -w1
This allows to set number of columns. From manpage of ls:
-w, --width=COLS
set output width to COLS. 0 means no limit
ls | tr "" "\n"
Easy, as long as your filenames don't include newlines:
find . -maxdepth 1
If you're piping this into another command, you should probably prefer to separate your filenames by null bytes, rather than newlines, since null bytes cannot occur in a filename (but newlines may):
find . -maxdepth 1 -print0
Printing that on a terminal will probably display as one line, because null bytes are not normally printed. Some programs may need a specific option to handle null-delimited input, such as sort
's -z
. Your own script similarly would need to account for this.
-1
switch is the obvious way of doing it but just to mention, another option is using echo
and a command substitution within a double quote which retains the white-spaces(here \n
):
echo "$(ls)"
Also how ls
command behaves is mentioned here:
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.
Now you see why redirecting or piping outputs one per line.
精彩评论