我如何提取仅有的tar 存档中目录中的文件?我需要提取目录中的所有文件,而不是特定文件。例如,具有以下结构的 tar 存档:
wordpress
--wp-admin
--wp-content
--wp-includes
--index.php
--license.txt
--readme.html
我只想提取 WordPress 目录中的 3 个(或更多)文件,而不是子目录。
请注意,我可以在此站点上找到的其他解决方案是关于提取特定文件的。我的问题是关于提取全部文件。
答案1
除非我可以对目录名和文件名的格式做出假设,否则我无法找到任何在特定级别提取文件的方法,而不在同一级别提取(空)目录。 (如果文件名包含点但目录不包含点,则另一个答案就足够了。)
考虑370358.tar
这个内容
wordpress/
wordpress/index.php
wordpress/license.txt
wordpress/readme.html
wordpress/wp-admin/
wordpress/wp-admin/admin.php
wordpress/wp-content/
wordpress/wp-content/2021/
wordpress/wp-content/2021/01/
wordpress/wp-content/2021/01/19/
wordpress/wp-content/2021/01/19/today.txt
wordpress/wp-content/content.txt
wordpress/wp-content/here.txt
wordpress/wp-content/some.txt
wordpress/wp-includes/
您可以wordpress/*
像这样提取匹配的文件
tar xf /tmp/370358.tar --wildcards --exclude '*/*/*' && rmdir */* 2>/dev/null
ls -R wordpress
wordpress:
index.php license.txt readme.html
注意后面的rmdir
.tar
即使生成的目录为空,我们也无法告诉跳过目录创建,因此我们只需在之后删除它们即可。
如果您实际上并不希望该wordpress
目录包含在提取中,
tar xf /tmp/370358.tar --strip-components 1 --wildcards --exclude '*/*/*' && rmdir * 2>/dev/null
ls -R
.:
index.php license.txt readme.html
答案2
假设使用 GNU tar
,您可以通过一个简短的脚本提取存档bash
:
tar -x -f archive.tar --to-command=./script.sh
...script.sh
可执行脚本在哪里
#!/bin/bash
if [ "$TAR_FILETYPE" = f ] &&
[[ $TAR_FILENAME == wordpress/* ]] &&
[[ $TAR_FILENAME != wordpress/*/* ]]
then
mkdir -p "${TAR_FILENAME%/*}" &&
cat >"$TAR_FILENAME" &&
chmod "$TAR_MODE" "$TAR_FILENAME" &&
chown "$TAR_UNAME:$TAR_GNAME" "$TAR_FILENAME" || true
else
cat >/dev/null
fi
这里使用的变量TAR_*
是由 GNU 在脚本环境中设置的tar
,当前提取的文件的数据是通过标准输入到达的。
脚本中使用的测试是为了确保
- 我们正在提取的文件是一个常规文件,并且
- 该文件位于该
wordpress
目录中,而不是其他地方。
要提取文件,我们只需确保文件的目录存在,将标准输入重定向到正确的文件名,然后修改文件模式和所有权,以便权限和所有者正确。
显然,您也可以在命令行上内嵌脚本tar
:
tar -x -f archive.tar --to-command='bash -c "
if [ \"\$TAR_FILETYPE\" = f ] &&
[[ \$TAR_FILENAME == wordpress/* ]] &&
[[ \$TAR_FILENAME != wordpress/*/* ]]
then
mkdir -p \"\${TAR_FILENAME%/*}\" &&
cat >\"\$TAR_FILENAME\" &&
chmod \"\$TAR_MODE\" \"\$TAR_FILENAME\" &&
chown \"\$TAR_UNAME:\$TAR_GNAME\" \"\$TAR_FILENAME\" || true
else
cat >/dev/null
fi"'
答案3
这会将目录中的所有文件提取到 tar 文件中,而无需进入子目录:
tar --wildcards --no-wildcards-match-slash -xvf file.tar.gz directory_in_tar/*.*