如何在“查找”输出中仅强制使用相对路径?

Sha*_*ane 28 linux command-line tar find recursive

我正在尝试创建一个脚本,该脚本可以将多个目录中具有特定扩展名的文件压缩为单个 tar 球。目前我在脚本文件中的内容是:

find "$rootDir" -name '*doc' -exec tar rvf docs.tar {} \;
Run Code Online (Sandbox Code Playgroud)

$rootDir搜索的基本路径在哪里。

这很好,除了 tar 文件中的路径是绝对的。我更喜欢路径相对于$rootDir. 我该怎么做呢?

当前的实施例tar -tf docs.tar,其中$rootDir/home/username/test输出:

home/username/test/subdir/test.doc
home/username/test/second.doc
Run Code Online (Sandbox Code Playgroud)

我希望输出是什么:

./subdir/test.doc
./second.doc
Run Code Online (Sandbox Code Playgroud)

小智 28

您可以使用指令中的%P格式-printf

find ${rootDir} -name '*.doc' -printf "%P\n"
Run Code Online (Sandbox Code Playgroud)

将显示在您的示例中:

subdir/test.doc
second.doc
Run Code Online (Sandbox Code Playgroud)

然后,您可以findfor表达式中使用此列表,以运行我们的 exec 命令,如下所示:

for f in $( find ${rootDir} -name '*.doc' -printf "%P\n" );
do
    tar rvf docs.tar ${f}
done
Run Code Online (Sandbox Code Playgroud)

  • 接受的解决方案有效,但基本上是一个黑客。恕我直言,这应该是问题的正确解决方案。 (5认同)

Dav*_*ett 11

如果您find从所需的根目录运行并且没有在find的选项中指定绝对起点,它将输出到tar它构造的命令调用的相对路径。像这样:

cd $rootDir
find . -name '*doc' -exec tar rvf docs.tar {} \;
Run Code Online (Sandbox Code Playgroud)

如果您不想永久更改当前工作目录并且正在使用bash或与您的 shell 类似,您可以这样做

pushd $rootDir
find . -name '*doc' -exec tar rvf docs.tar {} \;
popd
Run Code Online (Sandbox Code Playgroud)

反而。

请注意,并非所有 shell 中都存在 pushd/popd,因此请根据需要查看手册页。它们存在于 bash 中,但不在基本 sh 实现中,因此在显式使用时,/bin/bash您可以依赖它们,如果脚本要求,则不能依赖它们/bin/sh(因为这可能映射到没有 bash 增强功能的较小 shell)

  • 或者只使用 `cd $rootDir` 和 `cd -`(至少在 `bash` 中)。`( cd $rootDir ; find ... )` 也是可能的,即在子shell 中做所有事情。 (3认同)