2017-04-30 94 views
3

我想打印每一个文件的所有文件名在目录中一个.txt文件。打印列表(而不是文本文件本身)从终端

让我们假设我有一个目录,3个文件:

file1.txt 
file2.txt 
file3.txt 

,我试图用ls > output.txt

的事情是,当我打开output.txt我发现这个名单:

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

有没有一种方法,以避免打印在那里我重定向输出的文件的名称?或者更好的是,有一个命令能够打印除一个目录以外的所有文件的文件名?

+1

是否有一个原因,你必须打印输出在同一目录中的其他文件? – Jeremy

+2

@Jeremy对我来说使用它更简单。但是,是的,我可以在另一个目录中创建文件,完全避免该问题。我没有想到 – jackscorrow

回答

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

注意,这个假设没有预先存在output.txt文件 - 如果是这样,先删除它。

  • printf '%s\n' *使用globbing (filename expansion)通过线保持强劲打印所有文件,并且在当前目录下的子目录,行的名称。

  • 通配发生之前output.txt通过输出重定向> output.txt(这仍然发生前的命令是执行,这说明你的问题)创建的,所以在输出中包含它的名字是

  • Globbing还避免使用ls,其在脚本中的使用是generally discouraged

1

一般情况下,这是不好的解析的ls输出,尤其是在编写需要在良好的信誉很长一段时间的生产质量脚本。看到这个页面,以找出原因:Don't parse ls output

在你的榜样,output.txtls > output.txt输出的一部分,因为shell中运行ls之前安排的重定向(到output.txt)。

得到您的情况下,正确的行为,最简单的方法是:

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

,或者存储在一个隐藏的文件输出(或其他某个目录中一个正常的文件),然后将其移到最后的地方:

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

一个更通用的解决方案将使用grep -v

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

或者,您可以使用数组:

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

我认为它仍然与多行文件名相冲突,其中一行是'output.txt'(无可否认是一个奇特的情况)。至于另一种解决方案:为什么不使用字符串变量而不是单元素数组? '文件= “($ LS)”; printf'%s'“$ files”> output.txt' – melpomene

0

最安全的方式,而不承担有关文件名什么,是使用bash阵列(内存)或临时文件。临时文件不需要内存,所以它可能更安全。喜欢的东西:

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

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

  • 使用ls与忽略选项

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

-I, --ignore相同。这个选项和man page一样,不要列出匹配shell PATTERN的隐含条目。

  • 使用findfind

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

-name选项查找文件/目录,其名称相匹配的模式。 ! -name不包括名称与模式相匹配的名称。

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

%P条路径,并给出唯一的名字。

+1

您的命令假定使用_GNU_工具(Linux) - 请在您的答案中清楚说明这一先决条件。对于'find'命令是等价的,你(a)需要'-maxdepth 1'来防止递归,并且(b)你必须对文件名列表进行排序。 – mklement0

+0

我的机器上没有忽略选项。我没有使用Linux – jackscorrow