在 bash 中,如何仅列出文件?

在 bash 中,如何仅列出文件?

我希望只列出文件和目录,不列出额外数据。它用于解析数据,我不需要文件大小、权限等额外项目。

短暂性脑缺血发作

答案1

用于解析数据

解析——但是如何解析?

如果你在这样的 shell 中进行解析:

# don't
for f in $(dir); do my_parser "$f"; done

那么这是Bash 陷阱一号. 在这种情况下使用for f in ./*; do …

从现在开始我假设您通过管道进行解析,如下所示:dir | my_parser


不解析ls/的输出dir

dir来自您的答案) 可能是只是ls -C -b。 作为你不应该解析输出ls,您不应该解析任何一个的输出dir


您可以解析输出find

您可以通过管道传输find到解析器。解析时,包含换行符的路径名将被误解。要可靠地解析,请使用 GNU 的find-print0这将以空字符(而不是换行符)终止每个路径名。路径名本身不能包含空字符,因此不会产生歧义。POSIX 解决方案是-exec printf '%s\0' {} +。纯 POSIX 工具通常需要文本文件作为输入,并且它们可能不接受空字符,但如果您的解析器可以接受以空字符结尾的字符串,那么这就是您可以find从不支持的解析器中生成它们的方式-print0

find默认情况下下降到子目录。使用 GNU,find您可以通过指定 来更改此设置-maxdepth 1。POSIX find 的解决方案如下:将 POSIX 查找限制到特定深度。如果起点是.则解是\( -name . -o -prune \)

find starting_directory打印starting_directory为第一个路径名。我猜您不想获取这个特定的路径名​​。相关测试是! -path starting_directory(记住-path将其参数视为模式)。如果将起始目录指定为,.那么! -name .就足够了。使用 GNUfind -mindepth 1是一种替代方案,无论起始目录是什么,它都可以工作。

最终命令可以是下列之一:

find . -maxdepth 1 -mindepth 1                     # newline-terminated, GNU
find . \( -name . -o -prune \) ! -name .           # newline-terminated, POSIX
find . ! -name . -prune                            # newline-terminated, POSIX, simplified
find . -maxdepth 1 -mindepth 1 -print0             # null-terminated, GNU
find . ! -name . -prune -exec printf '%s\0' {} +   # null-terminated, POSIX

该列表并不详尽,还存在其他等效形式。

所有上述命令都会生成路径名以 开头的输出./(至少在find我测试的实现中是这样,但是显然 YMMV)。您可以通过管道 to sed 's|^\./||'(以换行符结尾时)或 to sed -z 's|^\./||'(以空字符结尾时;注意,-zGNU 支持此功能sed,但 POSIX 并不要求此功能)来删除此前缀。例如:

find . ! -name . -prune | sed 's|^\./||'

请记住,如果某些路径名包含换行符,则任何使用以换行符终止的路径名的解决方案都将失败或出现错误。


也许你甚至不需要find

如果您的解析器是用某种编程语言编写的,那么您应该使用该语言提供的任何方式列出文件,而不是依赖于独立的可执行文件,例如lsdirfind。应该有一种完全可靠的方法来迭代目录条目。

答案2

n/m.. 找到了。解决方案:dir

答案3

正如您所注意到的,dir是一个很好的选项,默认情况下它会执行您想要的操作,但等效命令ls- 作为更常见的工具,可能在类 Unix 系统上更为广泛使用 - 是ls -1(这是数字 1,而不是小写的 L)。

man ls

-1     list one file per line.

相关内容