如何将-exec中的重定向过滤为find命令?

时间:2014-05-06 13:05:24

标签: shell grep tar

我用Google搜索并阅读了很多博客,从未发现过这类问题。 我有一个脚本compress.sh,它通过cronjob调用。 cronjob执行得很好,并将邮件发送到 root ,该邮件包含在我的个人电子邮件中。

我收到了很多:

tar: Removing leading `/' from member names
tar: Removing leading `/' from member names

两个解决方案和两个问题!

FIRST WAY ,在命令中:

find /dir1/dir2/dir3/ -maxdepth 1 -mindepth 1 -not -path '*/\.*' -type d -exec tar czf {}_$(date +%Y_%m_%d_%H_%M_%S).tar.gz {} \;

我知道在哪里放置" -C /"参数,但我忽略了如何削减" {}"中的前导" /"

SECOND WAY ,在上面的命令中,在哪里放置 grep -v "tar : removing leading ...",以便过滤并将特定的错误消息发送到/ dev / null?

请注意,我更喜欢第一种(正确的)方式,但我也想知道如何使用第二种方法。

注意:这是因为我猜如果它是唯一的错误消息,一旦过滤,我将不会收到邮件......只有在出现另一个问题时才会发生。

2 个答案:

答案 0 :(得分:1)

要以第一种方式执行此操作 - 您无法直接处理{},但可以将其作为参数传递给bash,然后将其作为位置参数进行处理。所以而不是:

-exec tar czf {}_$(date +%Y_%m_%d_%H_%M_%S).tar.gz {} \;

您可以使用:

-exec bash -c 'tar czf "$0_$(date +%Y_%m_%d_%H_%M_%S).tar.gz" -C / "${0#/}"' {} \;

不是直接使用-exec执行tar,而是调用bash子shell,将tar命令作为-c选项的参数传递。 {}作为第一个参数传递。然后可以在子shell中将其作为$0访问。 ${0#/}是一个参数扩展,它从$0的开头删除单个斜杠。

要以第二种方式执行此操作,您必须首先重定向stderr,以便可以对其使用grep -v,然后将其重定向回stderr,以便正常处理任何其他错误消息。您可以将其添加到命令的末尾:

find ... \; 2> >(grep -v "tar: Removing leading" >&2)

这会将stderr重定向到进程替换,然后对数据执行grep命令并将其重定向回stderr - 所以grep匹配的所有行都将被删除,其他所有行都将通过不变。

答案 1 :(得分:1)

第一种方式:

您可以使用bash删除最初的/.

find /dir1/dir2/dir3 -maxdepth 1 -mindepth 1 -not -path '*/\.*' -type d -exec bash -c 'a="{}" ; a=${a#/} ; tar czf $a_$(date +%Y_%m_%d_%H_%M_%S).tar.gz $a' \;

第二种方式:

您可以将标准错误传递给grep并过滤掉您不想要的消息。

blah |& grep -v "Removing leading"