如何使用一个命令分别解压多个 tar 文件?

如何使用一个命令分别解压多个 tar 文件?

我有很多像这样的 tar 文件:aa.tar、bb.tar、cc.tar,...

我想将它们解压到它们自己的目录,例如 aa/、bb/、cc/ ...

我试过这个:

ls | xargs -n1 -I {} tar -xvf {} -C `basename {} .tar`

这是行不通的。看来 {} 不能同时用作整个 tar 文件名及其不带.tar.

我怎样才能让它发挥作用?

答案1

您不能在执行时{}在命令替换(调用)中使用basename甚至xargs被称为。这意味着将尝试将目录更改为每个存档的tar名为(字面意思)的目录。{}

使用for循环,不需要xargs.例如

for t in *.tar ; do
  bn="$(basename "$t" .tar)"
  mkdir -p "$bn"
  tar -xvf "$t" -C "$bn"
done

也可以看看:为什么不是解析ls(以及该怎么做)?

答案2

您的命令不起作用的原因是命令替换(您用反引号编写的位)将在xargs启动之前执行一次。

既然你用 标记了这个xargs,我想我会给出一个xargs基于 的解决方案。

首先,要解压单个档案tar,您可以使用

dir=${archive%.tar}
mkdir -- "$dir" && tar -x -f "$archive" -C "$dir"

...假设$archive包含存档的文件名tar并且存档是普通的(未压缩)。

你显然可以循环这个

for archive in *.tar; do
    dir=${archive%.tar}
    mkdir -- "$dir" && tar -x -f "$archive" -C "$dir"
done

但这不会让我们使用 的一些常见(尽管非标准)功能xargs,例如并行运行多个命令。

要运行我们的初始命令,一次四个命令,tar必须将存档的名称输入xargs到其标准输入中。

我们可以这样做

printf '%s\n' *.tar | xargs ...

这显然假设没有存档的名称包含嵌入的换行符,但您可以通过使用来解决这个问题

printf '%s\0' *.tar | xargs -0 ...

如果你的实施xargs-0支持读取以 null 结尾的参数的非标准选项。

要在 from 中运行解包xargs,最简单的方法是在子 shell 中执行sh -c

printf '%s\0' *.tar |
xargs -0 -P 4 -I {} sh -c 'dir=${1%.tar}; mkdir -- "$dir" && tar -x -f "$1" -C "$dir"' sh {}

sh -cshell 脚本中,$1与我们的初始命令相同$archive,并且该脚本将为每个存档启动一次。如果您的实现支持,则选项-P 4xargs并行运行四个提取xargs-P选项,

相关内容