Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print list of files in a directory to a text file (but not the text file itself) from terminal

Tags:

bash

ls

I would like to print all the filenames of every file in a directory to a .txt file.

Let's assume that I had a directory with 3 files:

file1.txt
file2.txt
file3.txt

and I tried using ls > output.txt.

The thing is that when I open output.txt I find this list:

file1.txt
file2.txt
file3.txt
output.txt

Is there a way to avoid printing the name of the file where I'm redirecting the output? Or better is there a command able to print all the filenames of files in a directory except one?

like image 260
jackscorrow Avatar asked Apr 30 '17 17:04

jackscorrow


3 Answers

In general, it is not good to parse the output of ls, especially while writing production quality scripts that need to be in good standing for a long time. See this page to find out why: Don't parse ls output

In your example, output.txt is a part of the output in ls > output.txt because shell arranges the redirection (to output.txt) before running ls.

The simplest way to get the right behavior for your case would be:

ls file*txt > output.txt # as long as you are looking for files named that way

or, store the output in a hidden file (or in a normal file in some other directory) and then move it to the final place:

ls > .output.txt && mv .output.txt output.txt

A more generic solution would be using grep -v:

ls | grep -vFx output.txt > output.txt

Or, you can use an array:

files=( "$(ls)" )
printf '%s\n' "${files[@]}" > output.txt
like image 124
codeforester Avatar answered Nov 09 '22 18:11

codeforester


printf '%s\n' * > output.txt

Note that this assumes that there's no preexisting output.txt file - if so, delete it first.

  • printf '%s\n' * uses globbing (filename expansion) to robustly print the names of all files and subdirectories located in the current directory, line by line.

  • Globbing happens before output.txt is created via output redirection > output.txt (which still happens before the command is executed, which explains your problem), so its name is not included in the output.

  • Globbing also avoids the use of ls, whose use in scripting is generally discouraged.

like image 37
mklement0 Avatar answered Nov 09 '22 20:11

mklement0


ls has an ignore option and we can use find command also.

  • Using ls with ignore option

    ls -I "output.txt" > output.txt
    ls --ignore "output.txt" > output.txt
    

-I, --ignore are same. This option says, as in the man page, do not list implied entries matching shell PATTERN.

  • Using find

    find \! -name "output.txt" > output.txt
    

-name option in find finds files/directories whose name match the pattern. ! -name excludes whose name match the pattern.

    find \! -name "output.txt" -printf '%P\n' > output.txt

%P strips the path and gives only names.

like image 23
Hasan Rumman Avatar answered Nov 09 '22 19:11

Hasan Rumman