UNIX shell 脚本:如何递归地将文件向上移动一个目录?

UNIX shell 脚本:如何递归地将文件向上移动一个目录?

我有大量小文件 f,排列在如下目录结构中:

/A/B/C/f

A级目录有11个,每个目录约有100个B级目录,每个目录约有30个C级目录,每个目录都有一个文件f。

如何将所有文件向上移动一级?例如,给定以下文件集...

/A/B/C/f1
/A/B/C/f2 /A
/B/C/f3
/A/B/C/f4

我希望目录/A/B/包含 4 个文件,从 f1 到 f4。无需删除目录 C。

我希望这个问题已经解决,可能涉及findxargswhatnot。有什么想法吗?

干杯,

詹姆士

答案1

使用 GNU find(在 Linux 上找到)或任何其他支持以下功能的 find 非常简单-execdir

find A -type f -execdir mv -i {} .. \;

有标准find

find A -type f -exec sh -c 'mv -i "$1" "${1%/*}/.."' sh {} \;

使用 zsh:

zmv -Q -o-i 'A/(**/)*/(*)(.)' 'A/$1$2'

如果目录结构始终具有相同的嵌套级别,则不需要任何递归遍历(但先删除空目录):

for x in */*; do; echo mv -i "$x"/*/* "$x"/..; done

答案2

对于该组文件,可以这样做:

$ cd /A/B/C/
$ mv ./* ../

但我预计你的问题会更复杂一些...我无法回答这个问题...我不太确定你的目录结构是怎样的...你能澄清一下吗?

答案3

我的第一个猜测是

$ find A -type f -exec mv {} .. \;  

只要你不指定-depth就没问题。我还没有尝试过,所以在承诺之前先测试一下。

答案4

如果您只想移动叶目录中的文件(即,您不想移动/A/B/file/A包含B子目录的文件),那么这里有几种方法可以做到这一点:

两者都需要

leaf ()
{
    find $1 -depth -type d | sed 'h; :b; $b; N; /^\(.*\)\/.*\n\1$/ { g; bb }; $ {x; b}; P; D'
}
shopt -s nullglob

这个有效:

leaf A | while read -r dir
do
    for file in "$dir"/*
    do
        parent=${dir%/*}
        if [[ -e "$parent/${file##*/}" ]]
        then
            echo "not moved: $file"
        else
            mv "$file" "$parent"
        fi
    done
done

这会更快,但它不喜欢空的源目录:

leaf A | while read -r dir
do
    mv -n "${dir}"/* "${dir%/*}"
    remains=$(echo "$dir"/*)
    [[ -n "$remains" ]] && echo "not moved: $remains"
done

相关内容