Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've got this directory full of images, and I can do this:

echo *.jpg
image1.jpg image2.jpg image3.jpg # and so on

How can I get the output in a plain text file in this format?

image1.jpg
image2.jpg
image3.jpg
share|improve this question
add comment

2 Answers

up vote 5 down vote accepted

Avoid using ls, bash globs can do it better

printf '%s\n' *.jpg >output_file
share|improve this answer
    
Why is bash globbing better than using ls? –  Sjoerd Jan 26 '12 at 8:18
    
If you just want to print the list, ls is good. But if you want to process the files, glob is better: for file in * will work for files with spaces in their names, while ls | while read file will not. –  choroba Jan 26 '12 at 8:58
    
@choroba. I am completely in favour of using bash globbing here, but you can easily get ls to handle multiple spaces in a filename by using IFS=$'\n'. Yes, it is more of a hassle, but it isn't a show-stopper for ls. The main restriction with output from ls is that it can't easily handle \n in filenames other than via the -b option (print octal escapes for nongraphic characters) which makes it rather impractical when compared to using globbing... Come to think of it: when a filename does have \n in it, then perhaps ls -b is the easiset way to hanlde it in an output file. –  Peter.O Jan 26 '12 at 11:01
    
Ok, ls writes non-printable characters 'as is' when the output is sent to a pipe (I was misled from the terminal output). However, ls is a further process to start, and I try to avoid it whenever possible. –  enzotib Jan 26 '12 at 11:28
    
Can this be done recursively? –  Oxwivi Jan 26 '12 at 16:35
show 4 more comments

I'd prefer find over ls. With find you can specify a lot of options, such as directory depth (min and max), access/modified time, use regular expressions and a lot more. Have a look at the find manpage.

runejuhl@lapaz:~/Pictures$ find . -iname '*.jpg'|head
./2011/03/09/CIMG9447.JPG
./2011/03/09/CIMG9445.JPG
./2011/03/09/CIMG9444.JPG
./2011/03/09/CIMG9442.JPG
./2011/03/09/CIMG9443.JPG
./2011/03/09/CIMG9440.JPG
./2011/03/09/CIMG9441.JPG
./2011/03/09/CIMG9446.JPG
./2011/06/26/CIMG9512.JPG
./2011/06/26/CIMG9585.JPG

runejuhl@lapaz:~/Pictures$ find . -maxdepth 2 -iname '*.jpg' |head
./Webcam/2012-01-10-120822.jpg
./Webcam/2010-11-08-192524.jpg
./Webcam/2012-01-10-170146.jpg
./Webcam/2012-01-10-120928_4.jpg
./Webcam/2012-01-10-120835_4.jpg
./Webcam/2012-01-10-120928_3.jpg
./Webcam/2012-01-10-120828.jpg
./Webcam/2012-01-10-120928_2.jpg
./Webcam/2012-01-10-120945_1.jpg
./Webcam/2012-01-10-120945_2.jpg

To get only the filename, you can use the -printf argument:

-printf format

True; print format on the standard output, interpreting \' escapes and%' directives. Field widths and precisions can be specified as with the printf' C function. Please note that many of the fields are printed as %s rather than %d, and this may mean that flags don't work as you might expect. This also means that the-' flag does work (it forces fields to be left-aligned). Unlike -print, -printf does not add a newline at the end of the string.

(look at the man page for more information)

To print only the filename, you'd use printf with "%f":

runejuhl@lapaz:~/Pictures$ find . -maxdepth 2 -iname '*.jpg' -printf '%f\n' |head
2012-01-10-120822.jpg
2010-11-08-192524.jpg
2012-01-10-170146.jpg
2012-01-10-120928_4.jpg
2012-01-10-120835_4.jpg
2012-01-10-120928_3.jpg
2012-01-10-120828.jpg
2012-01-10-120928_2.jpg
2012-01-10-120945_1.jpg
2012-01-10-120945_2.jpg

If using xargs, and passing the filename in this way, it might be a good idea to use "%f\0" and xargs -0 to use null delimiters.

When you feel like it, have a look at the -print0 argument and a real good look at xargs or parallel

share|improve this answer
    
Is it possible to only retrieve and save the names of the files minus the directory? –  Oxwivi Jan 27 '12 at 7:38
    
Yes, no problem. You can use the <code>-type</code> argument to specify which types. (I just read the question again, this isn't what you're looking for. I'll update my reply later today.) –  runejuhl Jan 28 '12 at 9:42
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.