- Print list of files in a directory to a text file (but not the text file itself) from terminal
- 6 Answers 6
- How to Redirect Output to a File and Stdout in Linux
- Redirecting Output to a File in Linux
- Redirect Output to File in Linux
- Appending Output to a File in Linux
- Discard Output to “/dev/null” in Linux
- Redirecting Output to Stdout in Linux
- Using “echo” Command
- Using “tee” Command
- Using “pip” Command
- Redirect all output to file in Bash [duplicate]
- 9 Answers 9
Print list of files in a directory to a text file (but not the text file itself) from terminal
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
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?
@Jeremy It’s just easier for me to work with it. But yes, I could create the file in another directory completely avoiding the problem. I didn’t think about that
6 Answers 6
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.
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
files=( "$(ls)" ) printf '%s\n' "$" > output.txt
I think that still runs afoul of multiline filenames where one of the lines is output.txt (admittedly an exotic case). As for the other solution: Why not just use a string variable instead of a single-element array? files=»($ls)»; printf ‘%s’ «$files» > output.txt
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.
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.
Your commands assume the use of GNU utilities (Linux) — please make that prerequisite clear in your answer. For the find commands to be equivalent, you (a) need -maxdepth 1 to prevent recursion, and (b) you must sort the list of filenames.
The most safe way, without assuming anything about the file names, is to use bash arrays (in memory) or a temporary file. A temporary file does not need memory, so it may be even safer. Something like:
#!/bin/bash tmp=$(tempfile) ls > $tmp mv $tmp output.txt
Using ls and awk commands you can get the correct output.
ls -ltr | awk '/txt/ ' > output.txt
This will print only filenames.
Note that shell will always expand all globs before running it. In your specific case, the glob expansion process goes like:
# "ls *.txt > output.txt" will be expanded as ls file1.txt file2.txt file3.txt > output.txt
The reason why you get «output.txt» in your final output file is that redirection actually works among all connected programs SIMULTANEOUSLY.
That means the redirection process does not occur at the end of the program ls , but happens each time ls yields a line of output. In your case, when ls finishing yield the very first line, the file «output.txt» would be created, which will finally be return by ls anyway.
How to Redirect Output to a File and Stdout in Linux
In the world of Linux, redirecting output to a file or the standard output (stdout) is a fundamental technique that allows us to capture and manipulate command output efficiently.
Whether you are a beginner or an experienced user, understanding how to redirect output can greatly enhance your productivity and provide you with more control over your command-line operations.
Through this guide, you will learn the process of redirecting output to a file and stdout in Linux.
Redirecting Output to a File in Linux
At some point where you want to save or redirect command output into a specific file for any reason, like debugging. In Linux, to save the output of a file, we use stdout, which is also known as the stream command.
In computing, the stream is something that transfers data. In our case, it is text data. Using stdout, we can stream and save that data into a text file for future use.
Before proceeding ahead, First, you should know what is Redirection and a combination of operators.
A redirection symbol directly redirects the command into a file instead of showing output on a terminal. There is a combination of redirection symbols that you can use like “>” , ”>>” , ”&>” , ”&>>” .
In Linux, what we type is called “stdin”, and the output we receive is known as “stdout”. If the output file does not exist in a specific location, it will recreate automatically and save the file.
Make sure if you have used “>” , then the past data will replace with fresh command output. If you want to redirect both “stdout” and “stderr”, then use “&>” .
Now we will use this redirection symbol to redirect the output into the file.
Redirect Output to File in Linux
When you use “>” redirection operator, it will redirect command output into a specific file. If you used the same file again to redirect, then the last output will be overwritten.
We will demonstrate it using the pwd command and hostnamectl command to show system info with a redirect “>” to save output into demofile.txt.
First, we will save the current working directory output to a file.
Now we will redirect the second output into the file.
Now view the contents of the file.
Appending Output to a File in Linux
When you use this “>>” redirection operator, it will redirect command output into a specific file, and ensure that the last saved data should not get a wiped and append new output into the same file.
For example, we will again use the pwd and hostnamectl commands to show system information with a redirect “>>” to save output into demofile.txt.
$ pwd > demofile.txt $ hostnamectl >> demofile.txt $ cat demofile.txt
From the above output, you can see all the past outputs are still available in the same file.
Discard Output to “/dev/null” in Linux
Sometimes you may want to discard output entirely. In such cases, you can redirect output to the “/dev/null” device file, which acts as a black hole for data.
In this example, the ls command lists the contents of the current directory, but the output is redirected to /dev/null. This effectively discards the output, as /dev/null acts as a black hole for data. No file is created or overwritten, and the output is not visible in the terminal or saved anywhere.
Redirecting Output to Stdout in Linux
Redirecting output to stdout allows you to display command output on the terminal or use it as input for other commands.
Here are some common methods to perform this process on your Linux system.
Using “echo” Command
The echo command is another way to output text or variables to stdout; by using redirection, you can redirect the output to the terminal or a file.
$ echo "Hello, Linux Users!" > output.txt
Using “tee” Command
The “tee” command reads from standard input and simultaneously writes to both stdout and files, helping you to display output on the terminal and save it to a file simultaneously.
$ ls | tee directory_lists.txt
The above command displays the output on the terminal as soon as you execute it and save the information in the “directory_list.txt” file. You can retrieve the information from this file using the cat command later on.
Using “pip” Command
In Linux, you can chain commands together using pipes (|) to redirect output from one command as input to another. This allows you to perform complex operations.
In this example, the ls command lists the contents of the current directory, and the output is then piped (|) to the grep command, which searches for lines containing the word “file” in the output of ls, enabling you to filter the output of one command and pass it as input to another command.
Conclusion
Understanding how to redirect output to a file and stdout in Linux is a crucial skill that can greatly enhance productivity and provide greater control over command-line operations.
By utilizing methods such as using the «>» operator, appending output to a file, discarding output with “/dev/null” and redirecting output to stdout using commands like “echo,” “tee” and piping, you can streamline your workflow and efficiently manage command output in your Linux environment.
Redirect all output to file in Bash [duplicate]
I know that in Linux, to redirect output from the screen to a file, I can either use the > or tee . However, I’m not sure why part of the output is still output to the screen and not written to the file. Is there a way to redirect all output to file?
9 Answers 9
That part is written to stderr, use 2> to redirect it. For example:
foo > stdout.txt 2> stderr.txt
or if you want in same file:
Note: this works in (ba)sh, check your shell for proper syntax
well, i found the reference and have deleted my post for having incorrect information. from the bash manual: ‘»ls 2>&1 > dirlist» directs only the standard output to dirlist, because the standard error was duplicated from the standard output before the standard output was redirected to dirlist» 🙂
also from the bash man «There are two formats for redirecting standard output and standard error: &>word and >&word Of the two forms, the first is preferred. This is semantically equivalent to >word 2>&1»
Two important addenda: If you want to pipe both stdout and stderr, you have to write the redirections in the opposite order from what works for files, cmd1 2>&1 | cmd2 ; putting the 2>&1 after the | will redirect stderr for cmd2 instead. If both stdout and stderr are redirected, a program can still access the terminal (if any) by opening /dev/tty ; this is normally done only for password prompts (e.g. by ssh ). If you need to redirect that too, the shell cannot help you, but expect can.
All POSIX operating systems have 3 streams: stdin, stdout, and stderr. stdin is the input, which can accept the stdout or stderr. stdout is the primary output, which is redirected with > , >> , or | . stderr is the error output, which is handled separately so that any exceptions do not get passed to a command or written to a file that it might break; normally, this is sent to a log of some kind, or dumped directly, even when the stdout is redirected. To redirect both to the same place, use:
EDIT: thanks to Zack for pointing out that the above solution is not portable—use instead:
If you want to silence the error, do: