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?
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
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.
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 infind
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With