UNIX shell 腳本:如何遞迴地將檔案向上移動一個目錄?

UNIX shell 腳本:如何遞迴地將檔案向上移動一個目錄?

我有大量小檔案 f,如下目錄結構排列:

/A/B/C/f

A級目錄有11個,B級目錄每個目錄有100個左右,C級目錄每個目錄有30個左右,每個目錄有一個檔案f。

如何將所有文件上移一級?例如,給定這組文件......

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

我希望該目錄/A/B/包含 4 個文件,從 f1 到 f4。不需要刪除目錄 C。

我希望這是一個已解決的問題,可能涉及findxargs、 和whatnot。有任何想法嗎?

乾杯,

詹姆士

答案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

相關內容