在我的 Ubuntu 系统上的一个大目录(> 140000 个文件和> 200 个子目录)中,我知道某处有两个文件名太长而无法复制到 Windows (NTFS) 文件夹。我试过了,收到了两条错误消息,但我没有注意文件所在的子文件夹。
如何找到名称最长的两个文件?
我猜@steeldriver 的解决方案是一个更好的选择,但这是我的替代解决方案,您可以使用命令组合来准确地找到两个(或更多)最长的文件名。
find . | awk 'function base(f){sub(".*/", "", f); return f;} \
{print length(base($0)), $0}'| sort -nr | head -2
Run Code Online (Sandbox Code Playgroud)
输出将是这样的:
length ./path/to/file
Run Code Online (Sandbox Code Playgroud)
这是一个真实的例子:
42 ./path/to/this-file-got-42-character-right-here.txt
31 ./path/to/this-file-got-31-character.txt
Run Code Online (Sandbox Code Playgroud)
find 为我们提供了该目录中所有文件的列表,例如:
./path/to/this-file-got-31-character.txt
Run Code Online (Sandbox Code Playgroud)
使用awk我们将文件长度添加到每一行的开头(这正是文件长度而不是路径的长度):
31 ./path/to/this-file-got-31-character.txt
Run Code Online (Sandbox Code Playgroud)
最后我们根据文件长度对其进行排序,并使用head.
根据评论,在这种情况下,您真正需要的是名称长于最大字符数的所有文件的列表 - 幸运的是,使用正则表达式相对find容易:
find $PWD -regextype posix-extended -regex '.*[^/]{255,}$'
Run Code Online (Sandbox Code Playgroud)
对于如此大量的文件和目录,您可能希望避免排序 - 相反,让我们只保留最长和第二长文件名及其完整路径名的运行记录:
find $PWD -printf '%p\0' | awk -v RS='\0' '
{
# get the length of the basename of the current filepath
n = split($0,a,"/");
currlen = length(a[n]);
if (currlen > l[1]) {
# bump the current longest to 2nd place
l[2] = l[1]; p[2] = p[1];
# store the new 1st place length and pathname
l[1] = currlen; p[1] = $0;
}
else if (currlen > l[2]) {
# store the new 2st place length and pathname
l[2] = currlen; p[2] = $0;
}
}
END {
for (i in l) printf "(%d) %d : %s\n", i, l[i], p[i];
}'
Run Code Online (Sandbox Code Playgroud)
或使用 GNU awk(支持 2D 数组)
$ find $PWD -printf '%p\0' | gawk -v RS='\0' '
{
# get the length of the basename of the current filepath
n = split($0,a,"/");
currlen = length(a[n]);
if (currlen > p[1][1]) {
# bump the current longest to 2nd place
p[2][1] = p[1][1]; p[2][2] = p[1][2];
# store the new 1st place length and pathname
p[1][1] = currlen; p[1][2] = $0;
}
else if (currlen > p[2][1]) {
# store the new 2st place length and pathname
p[2][1] = currlen; p[2][2] = $0;
}
}
END {
for (i in p[1]) printf "(%d) %d : %s\n", i, p[i][1], p[i][2];
}'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2761 次 |
| 最近记录: |