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 Avoid using ls, bash globs can do it better
printf '%s\n' *.jpg >output_file ls? 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. 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. 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. 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 theprintf' 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