unix 如何使用'find'命令(来自Cygwin)来打印值列表(文件大小,文件名),不管目录/文件名中出现什么字符?

eqzww0vc  于 2023-10-18  发布在  Unix
关注(0)|答案(2)|浏览(170)

给定某个目录的路径(即path/to/directory),我想获得以下格式的输出:

100|path/to/directory/a/file1.txt
200|path/to/directory/b/file2.txt
321|path/to/directory/c/d/file3.txt
...

这里是100、200、321等。是相应文件的大小(以字节为单位)(符号|用作分隔符)。
我尝试使用以下命令:

find path/to/directory -maxdepth 3 -type f -printf "%s|%p\n" > path/to/output.txt

但是,我收到了很多以下形式的错误消息:

find: `path/to/directory/my directory 1': No such file or directory

我注意到,当某些目录的名称至少包含一个空格时,就会发生这种情况。所以我的问题是无论文件名和目录名中出现什么字符,我可以使用什么命令来生成所需的输出?
该问题不是this问题的重复,因为存在有问题的名称的附加问题。This回答提到了包含白色空格的文件名或文件名的问题,然后说可以通过-print0 | xargs -0解决,然后说完全避免使用xargs结构更容易。我已经找到了一个相关的答案here,但无法修改它,使其符合我的需要。

编辑

我已经找到了导致问题的原因。问题是,我从Cygwin或MSYS2运行这些命令,这导致this problem,因为长文件名包含由多个字节编码的字符。这个问题也被描述为herehere。因此,Cygwin和MSYS2无法处理某些路径不超过操作系统(Windows)允许的最大长度(255个字符)的文件。例如,我创建了一个文件,其完整路径(在Windows中)如下所示:

E:/test1/αβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγ.txt

然后运行以下命令:

find E:/test1 -maxdepth 3 -type f -printf "%s|%p\n" > E:/test2/output.txt

但我得到了以下错误:

find: ‘E:/test1/αβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγαβγα\316’: No such file or directory

据我所知,它无法修复。

omtl5h9j

omtl5h9j1#

我想你可以这样做

find path/to/directory -type f -exec stat -c "%s|%n" {} \;
  • -exec stat -c "%s|%n" {} \;为找到的每个文件执行stat命令,%s表示文件大小(以字节为单位),%n表示文件名,|字符用作大小和路径之间的分隔符!

你也可以试试这个:

find path/to/directory -maxdepth 3 -type f -exec sh -c 'size=$(stat -c "%s" "$1"); echo "$size|$1"' sh {} \; > path/to/output.txt
oprakyz7

oprakyz72#

通过TXR Lisp使用nftw函数:

$ txr sizepath.tl /usr/share/man
2408|/usr/share/man/vi/man1/help2man.1.gz
2246|/usr/share/man/ru/man8/groupmems.8.gz
2451|/usr/share/man/ru/man8/groupmod.8.gz
[...]

nftw POSIX C库函数有一个在标准中指定的FTW_CHDIR标志,它使函数在它遍历的每个目录中执行chdir
我相信,当使用FTW_CHDIR时,nftw不会受到长路径的阻碍,因为在内部,它使用短的相对路径来进行下降。
在TXR Lisp中,此标志值显示为变量ftw-chdirsizepath.tl程序是:

(ftw *args*
     (lambda (path type stat . rest)
       (when (eql type ftw-f)
         (put-line `@{stat.size}|@path`)))
     ftw-chdir)

无论您是否使用ftw-chdir,回调函数的path参数都指定了完整路径,就好像chdir调用没有发生一样;也就是说,如果起始点是相对路径,那么path将是从原始目录开始的相对路径。如果我们必须打开文件,我们必须使用(base-name path),但我们没有:ftw给出了一个stat参数,它是stat结构;我们只需要从中提取size字段。
虽然nftw是一个POSIX函数,但它可以在Windows版本的TXR中工作,TXR包含一个扩展的POSIX运行时库。
在Windows 10 cmd.exe提示符下:

C:\Users\kaz>copy con sizepath.tl
(ftw *args*
     (lambda (path type stat . rest)
       (when (eql type ftw-f)
         (put-line `@{stat.size}|@path`)))
     ftw-chdir)
^Z
        1 file(s) copied.

C:\Users\kaz>txr sizepath C:\Users\kaz\AppData\Local\Microsoft
51959|C:\Users\kaz\AppData\Local\Microsoft/CLR_v4.0/ngen.log
2339|C:\Users\kaz\AppData\Local\Microsoft/CLR_v4.0/UsageLogs/AsusJWTDecoder.exe.log
1327|C:\Users\kaz\AppData\Local\Microsoft/CLR_v4.0/UsageLogs/AsusLiveUpdateToast.exe.log
[...]

包含驱动器号名称和所有内容的本机路径。

相关问题