折叠bash中的嵌套目录

时间:2015-05-13 20:43:19

标签: bash

通常在解压缩文件后,我最终会得到一个只包含其他目录的目录(例如,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

虽然第二种方法似乎有效,但还有更好的方法来实现这一目标吗?

2 个答案:

答案 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实现。