我需要创建一个大于 10G 的文件列表,这些文件将作为重复备份的忽略文件输入。但是,我有一些我无权读取的文件。我想忽略那些稍后将处理的内容,并使列表变得干净,没有“权限被拒绝”消息。
我可以这样列出清单:
$ find data/ -size +10G
/data/bigfile1
find: `/data/badfile1': Permission denied
find: `/data/badfile2': Permission denied
/data/bigfile2
然后我需要删除包含“权限被拒绝”或“查找:”字符串的行。我不确定列表输出的顺序是否相关,但这就是我所看到的。我正在尝试多种选择,但无法删除这些线条。我正在关注这个问题,看起来很相似,但我不明白为什么它不起作用。 https://stackoverflow.com/questions/3548453/negative-matching-using-grep-match-lines-that-do-not-contain-foo
我正在尝试方法,首先使用 grep:
$ find data/ -size +10G | grep -v 'find:'
find: `/data/badfile1': Permission denied
/data/bigfile1
find: `/data/badfile2': Permission denied
/data/bigfile2
还使用 awk:
$ find data/ -size +10G | awk '!/find:/'
find: `/data/badfile1': Permission denied
find: `/data/badfile2': Permission denied
/data/bigfile1
/data/bigfile2
无论如何,积极选择效果很好。所以我不知道该怎么办。
答案1
IO重定向
问题不在于您的脚本,而在于特征UNIX IO 重定向。
考虑以下命令
find data/ -size +10G | grep -v 'find:'
仅stdout
流被发送到管道grep
命令,错误消息位于单独的输出流中stderr
。
因此,即使您在终端会话中看到错误消息,由于终端同时打印stdout
和stderr
到控制台,您的grep
命令是不是接收这些输出行。这是由于|
重定向输出的方式所致。该管道|
仅连接stdout
到下一个命令stdin
,因此stderr
不会进入下一个命令。
大多数*NIX
实用程序都以这种方式运行,将错误发送到stderr
输出流,以便在您遇到的情况下无需过滤掉这些消息。
测试
stdout
要查看上面的命令在传递时的具体情况,请grep
执行以下操作:
find data/ -size +10G > out.txt
您应该仍会在控制台中看到错误,但stdout
输出流将转到一个新文件out.txt
.看看那里,你不会看到错误消息行。