views:

98

answers:

3

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 updator_error_log.txt

Is there a built-in alternative to get filenames, each on a new line, like this:

.  
..  
.bash_history  
.ssh  
updator_error_log.txt
+4  A: 

Yes:

ls -a | cat

Explanation: The command ls senses if the output is to a terminal or to a file or pipe and adjusts accordingly.

Peter G.
+4  A: 

Use man ls to see if your ls supports the -1 option (that the "one" digit, not a lowercase letter "L" - thanks @slashmais), e.g.

http://docs.sun.com/app/docs/doc/819-2239/ls-1

...

-1

   Prints one entry per line of output.

GNU/Linux's ls does support it, so use:

ls -1a
Bert F
Ah, now if only every system had the documentation installed...
dty
+1 I didn't know about -1 (-l yes (ell not one)) It shows in the man-page but I've been reading it as an ell the whole time :)
slashmais
@slashmais - Ah, good point - easy to mistake. I clarified in the answer.
Bert F
@dty: for GNU, you get this documented in `ls --help` output... always installed ;-)
Tony
@Tony, I know. I was being sarcastic.
dty
@dty: ok... but enough systems lack the man and/or info pages, so it didn't read that way :-).
Tony
A: 

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.

Gilles
@Gilles - I'm connected via SSH to the remote machine. I found no way to execute a python function like os.listdir on the remote machine in a single line. Hence, this question. I don't want to write a script for simply listing files. Is there anyother way around this problem?
fixxxer
@fixxxer: ssh does change the situation, it's the sort of things you should have mentioned in your original question! I think sftp is appropriate for your use case.
Gilles
I'm sorry for the confusion. Is there a way I can insert the password in the "command_line" as well?
fixxxer
@fixxxer: I don't know, the authors of ssh frown on passwords stored in plain text and tend not to make this easy. You should really set up key-based authentication (there are plenty of tutorials on the web and questions on http://superuser.com/ about this).
Gilles