我有很多像这样的 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 -c
shell 脚本中,$1
与我们的初始命令相同$archive
,并且该脚本将为每个存档启动一次。如果您的实现支持,则选项-P 4
将xargs
并行运行四个提取xargs
-P
选项,