经常在解压缩文件后,我最终会出现一个只有另一个目录的目录(例如, 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
的错误。
虽然第二种方法似乎有效,但有更好的方法可以实现这一目标吗?
打开dotglob
shell选项,该选项允许您的模式以.
开头匹配文件。
shopt -s dotglob
mv -i "$1"/* .
rmdir "$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规范的一部分,而是在Common GNU和OSX/BSD实现上。