Xargs:在执行之前将工作目录更改为文件路径?

fdm*_*ion 6 xargs working-directory

我有一个很大的 RAR 档案文件夹。文件夹级别有明显的层次结构。我想一次解压缩整个档案集。

我有以下单线,可以工作:

find -name "*.rar" -print0 | xargs -0 -n 1 -P 4 unrar x
Run Code Online (Sandbox Code Playgroud)

(请注意,我们并行运行四个线程以加快操作速度。:-))

此命令的问题在于 xargs 是在每个 RAR 文件的顶级目录中执行的。这意味着所有输出都被转储到顶级文件夹中。

相反,我希望输出与 RAR 存档存在于同一文件夹中。

例子:

Top level
 |--FolderA
 |----File1.rar
 |----File2.rar
 |--FolderB
 |----File1.rar
 |----File2.rar
 |----File3.rar
 |--FolderC
 |----File1.rar
 |----File2.rar
Run Code Online (Sandbox Code Playgroud)

每个“File1.rar”文件都包含一个同名文件。因此,将它们全部提取到顶级文件夹会导致覆盖问题。

总而言之,我想提取上述层次结构中的所有 RAR 文件。我希望每个 RAR 文件的内容都存在于 RAR 文件所在的文件夹中。

在我看来,解决方案是以某种方式设置工作目录,然后在那里运行 unrar 命令表单。但是,由于 find 命令给了我文件名,而不是目录,我不能做类似的事情

| xargs -I{} -n 1 -P 4 cd {} \; unrar x {}
Run Code Online (Sandbox Code Playgroud)

没有编写一个 Perl 或 Python 脚本来环绕 unrar 命令并处理将提供的路径分成其部分并执行命令,有没有更好的方法来实现这一点?

jjl*_*lin 5

存在从路径中提取目录名 ( dirname) 和文件名 ( basename) 的命令。所以你可以做类似的事情

find . -name '*.rar' -print0 | \
xargs -0 -I{} -n1 -P4 /bin/sh -c 'cd "$(dirname {})"; unrar x "$(basename {})"'
Run Code Online (Sandbox Code Playgroud)

AFAIK,xargs不支持更改目录,所以你需要一些中介来做到这一点,因此/bin/sh. 你提到在 周围写一个包装器unrar,这基本上就是这样做的,除了单行形式。