假设我有如下文件:
$ tree
.
├── 01/
│ ├── example.txt
│ └── foobar.txt
├── 02/
│ └── example.txt
└── 03/
├── example.txt
└── test.txt
3 directories, 5 files
我希望find .
按顺序按顺序打印目录和文件(即目录名在内容之前),并按字母顺序在同一目录中打印。相反,这些是我得到的结果:
$ find .
.
./02
./02/example.txt
./01
./01/foobar.txt
./01/example.txt
./03
./03/test.txt
./03/example.txt
我希望输出结果如下:
.
./01
./01/foobar.txt
./01/example.txt
./02
./02/example.txt
./03
./03/example.txt
./03/test.txt
我不想把管道输送到sort
或任何其他命令,因为我想在find
命令完成之前逐一处理这些行。
发布于 2021-08-23 15:59:29
你不能这么做。
如果要按特定顺序处理文件,则必须在开始处理这些文件之前按该顺序排列它们。
find
在文件系统(通常称为“目录顺序”)中以任何顺序查找文件/目录,许多文件系统主要受创建日期的影响,但如果您删除文件/目录,它们的位置可能会被重用,因此基本上应该假定它是随机的),在您的情况下,这似乎不是字母顺序。但是,按字母顺序排列,可能是文件系统中的最后一个,因此,如果要按字母顺序处理文件,则需要读取整个目录。
要获得最接近您想要的结果,您可能需要进行一些编码。如果您扫描(搜索的)顶级目录,您知道接下来要扫描'01‘目录,然后是'02’、.和当'02‘(和随后的目录)被扫描时,您可以开始处理'01’中的文件。(如果您的目录结构更通用,则酌情进行概括。)
发布于 2021-08-23 15:28:04
使用GNU find
、sort
和xargs
:
find . -print0 | sort -z | xargs -0r process_the_files
process_the_files
是您本来可以使用find的-exec
选项运行的任何程序或脚本。
这使用NUL作为文件名分隔符,贯穿管道(-print0、-z和-0选项),因此可以安全地使用包含任何有效字符(包括空格、制表符、换行符等)的文件名。
如果您想通过find (而不是那些文件的内容)处理文件名列表,您可以:
process_the_files
脚本,以便它能够迭代文件名参数,而不是这些文件的内容。请注意,如果文件名列表太大,无法在一个命令行中运行,xargs可能不止一次运行process_the_files
(在Linux上,这个命令行的大小各不相同,在Linux上大约为2MB)。顺便说一句,find ... -exec ... {} +
也受到系统命令行长度的限制。xargs
部分,只需将管道排序的输出放到您想用它们做的任何事情中--但是必须能够处理以NUL分隔的输入(大多数GNU都可以,用awk或perl甚至sh变量都可以很容易地编写自己的输出,甚至sh -sh变量都不能包含空值,但是当您仅仅使用NUL作为分隔符时,这并不重要)。这样做并不受命令行长度限制的限制,它可以处理来自stdin的任意数量的文件名。https://unix.stackexchange.com/questions/665909
复制相似问题