bash 从终端将目录中的文件列表打印到文本文件(但不是文本文件本身)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43709025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 16:06:20  来源:igfitidea点击:

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

bashls

提问by Hymanscorrow

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

我想将目录中每个文件的所有文件名打印到一个.txt文件中。

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

假设我有一个包含 3 个文件的目录:

file1.txt
file2.txt
file3.txt

and I tried using ls > output.txt.

我尝试使用ls > output.txt.

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

问题是,当我打开时,output.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?

有没有办法避免在我重定向输出的地方打印文件名?或者更好的是有一个命令能够打印目录中文件的所有文件名,除了一个?

回答by mklement0

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

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

请注意,这假定没有预先存在的output.txt文件 - 如果是,请先将其删除。

  • 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 beforeoutput.txtis created via output redirection > output.txt(which still happens before the command is executed, which explains your problem), so its name is notincluded in the output.

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

  • printf '%s\n' *使用globbing(文件名扩展)逐行打印位于当前目录中的所有文件和子目录的名称。

  • Globbing在通过输出重定向创建之前发生(这仍然发生在命令执行之前,这解释了您的问题),因此它的名称包含在输出中。output.txt> output.txt

  • Globbing 还避免使用ls通常不鼓励在脚本中使用。

回答by codeforester

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

一般来说,解析 的输出是不好的ls,尤其是在编写需要长时间保持良好信誉的生产质量脚本时。请参阅此页面以找出原因:不要解析 ls 输出

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

在您的示例中,output.txt是输出的一部分,ls > output.txt因为 shell 在运行之前安排了重定向(到 output.txt)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:

更通用的解决方案是使用grep -v

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

Or, you can use an array:

或者,您可以使用数组:

files=( "$(ls)" )
printf '%s\n' "${files[@]}" > output.txt

回答by Hasan Rumman

lshas an ignore option and we can use findcommand also.

ls有一个忽略选项,我们也可以使用find命令。

  • Using lswith ignore option

    ls -I "output.txt" > output.txt
    ls --ignore "output.txt" > output.txt
    
  • 使用ls与忽略选项

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

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

-I, --ignore是一样的。这个选项说,在手册页中,不要列出与 shell PATTERN 匹配的隐含条目。

  • Using find

    find \! -name "output.txt" > output.txt
    
  • 使用 find

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

-nameoption in findfinds files/directories whose name match the pattern. ! -nameexcludes whose name match the pattern.

-name中的选项find查找名称与模式匹配的文件/目录。 ! -name排除名称与模式匹配的人。

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

%P strips the path and gives only names.

%P 去掉路径并只给出名称。

回答by Ramin Ismayilli

Using lsand awkcommands you can get the correct output.

使用lsawk命令可以获得正确的输出。

ls -ltr | awk '/txt/ {print }' > output.txt

This will print only filenames.

这将只打印文件名。

回答by linuxfan says Reinstate Monica

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:

最安全的方法是使用 bash 数组(在内存中)或临时文件,而不对文件名做任何假设。临时文件不需要内存,所以它可能更安全。就像是:

#!/bin/bash
tmp=$(tempfile)
ls > $tmp
mv $tmp output.txt