Shell 命令过滤管道中不存在的文件

Shell 命令过滤管道中不存在的文件

我正在寻找一种好方法来生成一个备份 tar.gz,该文件将被另一个 tar.gz 的提取所覆盖。

tar -ztf patch.tar.gz | grep -v "/$" | tar -T- -zcvf backup.tar.gz

这很完美!但是,有时,新补丁 (patch.tar.gz) 不仅包含硬盘中已经存在的文件,还可能添加尚不存在的新文件。这些不存在的文件将无法备份,第二个 tar 将生成错误。退出代码为2

tar:文件夹/文件.txt:无法统计:没有这样的文件或目录
tar:由于之前的错误而以失败状态退出

我正在寻找仅检查文件存在(stdin)并在 stdout 上发送现有文件的 shell 命令。它存在吗?我需要这样的东西:

tar -ztf patch.tar.gz | grep -v "/$" | filterfileexist | tar -T- -zcvf backup.tar.gz

我需要一个 shell 命令而不是一个 shell 脚本。
显然,我可以自己用 C 实现这个 shell 命令,因为它非常简单,但我希望找到可以在其他 UNIX 平台上找到的通用命令。

答案1

尝试使用 perl oneliner 来实现这一点

喜欢

cat filelist | perl -ne 'chomp(); if (-e $_) {print "$_\n"}' | tar -T- -zcvf backup.tar.gz

答案2

这里有几个替代方案。

tar -ztf patch.tar.gz | grep -v “/$” | xargs -i sh -c'test -f {} && echo {}' | tar -T- -zcvf backup.tar.gz

或者

tar -ztf patch.tar.gz | grep -v “/$” | tar --ignore-failed-read -T- -zcvf backup.tar.gz

第二个示例在尝试备份不存在的文件后将以状态零退出(在 Centos 6.5 上测试),从而避免了该问题。

答案3

find与 一起使用xargs。 的默认行为是如果文件存在则find打印文件名到,不存在的文件将打印错误消息到stdoutstderr

$ echo existing-file missing-file | xargs find 2> /dev/null
./exisisting file

如果有目录,则添加-type f-maxdepth=0以防止 find 默认递归。

$ echo existing-file missing-file dir | xargs -I% find % -type f 2> /dev/null
./exisisting file

常见的空格警告适用。更安全的版本

$ echo existing-file missing-file 'annoying
name sudo rm -rf /' | tr '\n' '\0' | xargs -0 find 2> /dev/null

相关内容