通过 wc -l 通过管道传输每批 xargs

通过 wc -l 通过管道传输每批 xargs

所以我的任务是找到目录中硬链接最多的文件。到目前为止我有:

find . -name "file*" | xargs -I{} -n 1 find . -samefile {} 

这给了我:

./hardlinkFIle245
./hardlinkFIle23
./hardlinkFIle2
./file2.txt
./hardlinkFIle1234
./hardlinkFIle123
./hardlinkFIle12
./hardlinkFIle1
./file1.txt

现在,当我用管道将其输入时|wc -l,我得到了总行数 9:

find . -name "file*" | xargs -I{} -n 1 find . -samefile {} | wc -l

我想要的是每个 xargs batch -n 1 给我计数:所以我想要:

4
5

答案1

如果使用 GNU find,您可以让它报告链接数量-printf %n。所以你可以通过以下方式获得最大值:

find . -name 'file*' -printf '%n\n' | sort -rn | head -n1

.但请注意,该数字可能包含在与模式不匹配的条目下找不到的链接file*

如果您只想计算file*在 下找到的名为硬链接的数量.,并查看它们的路径,您可以这样做:

find . -name 'file*' -printf '%i\0%p\0' | gawk -v RS='\0' '
   {
     inode = $0
     getline file
   }
   ++count[inode] >= max {
     files[inode] = files[inode] " - " file ORS
     max = count[inode]
     max_inode = inode
   }
   END {
     printf "%s", "File with most links ("max"):\n" files[max_inode]
   }'

它仍然只运行一次find调用,而不是每个文件一次。

答案2

您可以在每个 xargs 上生成一个新的 shell:

find . -name "file*" | xargs -n 1 sh -c 'echo "$1"; find . -samefile "$1" | wc -l' xargs-sh

尽管在这里使用xargs是一个坏主意,因为如果文件路径包含引用字符的空格,它就会中断。

在这里,使用wc -l也很脆弱,因为如果文件路径包含换行符,它就会中断。

您可以使用标准语法并使用循环来find -exec cmd {} +节省每个文件运行一个的麻烦:sh

find . -name "file*" -exec sh -c '
  for file do
    printf "%s\n" "$file"
    find .//. -samefile "$file" | grep -c //
  done' find-sh {} +

相关内容