通常在解压缩文件后,我最终会得到一个只包含其他目录的目录(例如,mkdir foo; cd foo; tar xzf ~/bar.tgz
只能在bar
中生成foo
目录。我想编写一个脚本将其折叠到一个目录,但如果嵌套目录中有点文件,则会使事情变得复杂。
这是一个天真的实施:
mv -i $1/* $1/.* .
rmdir $1
此处唯一的问题是,它还会尝试移动.
和..
并询问overwrite ./.? (y/n [n])
。我可以通过依次检查每个文件来解决这个问题:
IFS=$'\n'
for file in $1/* $1/.*; do
if [ "$file" != "$1/." ] && [ "$file" != "$1/.." ]; then
mv -i $file .
fi
done
rmdir $1
但这似乎是一种不优雅的解决方法。我使用find
尝试了一种更干净的方法:
for file in $(find $1); do
mv -i $file .
done
rmdir $1
但find $1
也会提供$1
作为结果,错误为mv: bar and ./bar are identical
。
虽然第二种方法似乎有效,但还有更好的方法来实现这一目标吗?
答案 0 :(得分:3)
启用dotglob
shell选项,该选项允许您的模式匹配以.
开头的文件。
shopt -s dotglob
mv -i "$1"/* .
rmdir "$1"
答案 1 :(得分:1)
首先,请考虑许多tar
实现提供--strip-components
选项,允许您剥离第一个路径。不确定是否有第一条路径?
tar -tf yourball.tar | awk -F/ '!s[$1]++{print$1}'
将显示所有第一级内容。如果只有那个目录,那么
tar --strip-components=1 -tf yourball.tar
将tar中该目录的内容提取到当前目录中。
这样你就可以完全避免这个问题了。但它也是解决您眼前问题的方法。已经提取了文件,所以你有
foo/bar/stuff
foo/bar/.otherstuff
你可以做到
tar -cf- foo | tar --strip-components=2 -C final_destination -xf-
--strip-components
功能不是tar
的POSIX规范的一部分,但它同时适用于常见的GNU和OSX / BSD实现。