如果我给ls -1
我得到这样的,
file_0001.jpeg
file_0002.jpeg
file_0003.jpeg
file_0004.jpeg
file_0005.jpeg
file_0006.jpeg
file_0007.jpeg
file_0008.jpeg
file_0009.jpeg
file_0010.jpeg
file_0011.jpeg
file_0012.jpeg
file_0013.jpeg
file_0014.jpeg
file_0015.jpeg
file_0016.jpeg
file_0017.jpeg
file_0018.jpeg
file_0019.jpeg
file_0020.jpeg
file_0021.jpeg
...
file_0999.jpeg
有没有办法使用awk
或其他工具来查看是否以这种连续增量方式丢失了某些文件。
如果您使用的是
bash
shell,您可以使用seq
或jot
创建一个“完美”的输出参考样本,然后将输出ls -1
与该参考进行比较:这不仅会显示任何丢失的文件,还会发现无关文件。
虽然其他答案提供了准确查找丢失哪些文件的方法,但可以以更易于输入的方式检查查看某些文件是否丢失的原始问题。
您的列表是 的输出
ls -1
,因此通过管道将其输入 wc 应该会为您提供许多与最后一个条目的名称匹配的文件。ls -1 | wc -l
如果计数与最后一个文件的名称不匹配,则必须有一个丢失的文件。
您可以使用 awk 过滤掉丢失的。在 GNU Awk 上,支持多字符 FS,您可以将结果通过管道传输到
或使用
perl
如果预计会有更多空白,您可以
awk
打印出丢失的文件编号范围。修改以上内容您可以使用 过滤
comm
。例如,在包含此类文件的目录中缺少一些文件时:
您可以像这样过滤:
comm
是一个比较 2 个文件的命令,显示哪些行仅存在于文件 1 中,哪些行仅存在于文件 2 中,哪些行都存在于两者中。-1
抑制仅存在于文件 1 中的-2
行,抑制仅存在于文件 2 中-3
的行,并抑制存在于两者中的行。-13
与 相同-1 -3
,它会抑制除仅存在于文件 2 中的行之外的所有行,即生成的文件名。目录中的无关文件可以通过使用
-23
而不是列出-13
:不使用这些选项,可以看到缩进区分的所有内容。仅在文件 1 中的行没有缩进,仅在文件 2 中的行有 1 个制表符缩进,并且两者中都存在的行有 2 个制表符缩进:
使用 for 循环。
作为脚本
一个简单的方法是从
seq
命令循环数字只需在您自己的文件名中适应您的 4 位数字格式
(原来这个问题是重复的,我使用的与如何打印文件夹中丢失文件的名称的最佳答案相同?)
对于 bash 中的交互使用,快速且易于键入和记住:
我通常使用
{01..99}
大括号扩展来生成预期的系列并查找ls
错误:重定向隐藏了现有文件的标准输出列表,但标准错误仍然连接到终端。
>/dev/null
如果文件少于〜100个,我有时会忽略并在终端中向后滚动,因为错误消息首先出现,而ls
在排序和打印它们之前仍在阅读其参数。这也验证了我是否输入正确并且我的模式与我想要的文件匹配(尤其是如果它包含一个 glob)。对于管道/捕获,您可以
foo=$(ls ... 2>&1 >/dev/null)
将 stderr 重定向到管道,然后将 stdout 重定向到 /dev/null,同时让 stderr 进入 shell 的管道。这对于检查空/非空错误输出很有用。但是在脚本中,如果您想获取丢失文件的名称ls
,请查看其他答案,而不是尝试将其从可能被国际化的错误消息中解析出来等。如果需要 / 如果需要,可以在文件名的其他部分使用引号,例如
'foo bar '{01..22}.jpg
. 甚至foo\ bar\ {01..22}*.jpg
扩展为'foo bar '01*.jpg
/'foo bar '02*.jpg
等,因此即使在序列号以外的某个地方的某些或所有文件有一些额外的唯一名称,它也可以工作。即使您的编号不使用前导零(例如
{1..99}
代替{01..99}
. 如果您想在大括号范围内包含前导零,您可以{01..09}
按照您希望的方式执行类似的操作,而不是像我在示例中所做的那样将它们从大括号表达式中分解出来。请注意,现代 Linux 系统支持非常长的 arg 列表,例如 128kiB 的 text。这种方法确实依赖于生成一个包含每个文件的命令行。这对于交互式使用来说是 100% 没问题的:在列表太大的罕见情况下,shell 会告诉你它。
另一个答案
for
在列表上使用了一个循环,这会更慢(ls
为每个文件启动一个单独的文件),但即使在巨大的或更有限的系统上也安全,argv 限制要小得多。