mv 和 cp 目錄層次結構?

mv 和 cp 目錄層次結構?

mv當我或cp檔案時,我還可以移動或複製檔案的目錄層次結構嗎?

例如,如果 Imvcp dir1/dir2/file其他地方,它只會mvcp file。如果我也想mv或怎麼辦cp dir1/dir2?不是mkdir -p dir1/dir2可以用一個指令來完成嗎?

答案1

您可以使用cp--parents開關:

$ mkdir -p step1/step2/step3
$ touch step1/step2/step3/file
$ mkdir copy

$ cp --parents step1/step2/step3/file copy
$ ls copy/step1/step2/step3/file
copy/step1/step2/step3/file

mv但是,沒有開關--parents,但您可以執行以下操作:

$ find step1/step2/step3 -name "file" -exec cp --parents {} copy/ \; -delete

這將:

  • 找到該文件。
  • 將其(及其父級)複製到目的地。
  • 刪除原來的。

您可以為此建立一個函數:

mvparents()
{
    [[ $# -ne 2 ]] && echo "2 arguments needed." && return
    [[ ! -r "$1" ]] && echo "$1 is not readable." && return
    [[ ! -d "$2" ]] && mkdir -p "$2"

    find $(dirname $1) -name "$(basename $1)" -exec cp --parents {} $2/ \; -delete
}

$ mvparents step1/step2/step3/file copy/

如果您嘗試移動多個文件,這可能需要進行一些調整。這是一個範例(在 bash 中工作,但不保證其他 shell):

mvparents()
{
    [[ $# -lt 2 ]] && echo "Usage: $0 [source] <source> ... [destination]." && return

    # Get the destination directory.
    for dest; do true; done
    [[ ! -d "$dest" ]] && mkdir -p "$dest"

    # Copy the arguments and remove the destination.
    parameters=( "$@" )
    unset parameters[${#parameters[@]}-1]

    # For each source file: find, copy, delete.
    for source in "${parameters[@]}"; do
        if [ -r "$source" ]; then
            find $(dirname $source) -name "$(basename $source)" -exec cp --parents {} $dest/ \; -delete
        else
            echo "$0: $source is not readable."
        fi
    done
}

嗯......這比我預期的要長一點,但它應該可以完成工作

編輯:作為塞巴斯蒂安·皮耶希在評論中指出,依靠cpto domv的工作是相當性能殺手,因為mv本來不需要複製文件,只需編輯其元資料即可。您可能想將上面的循環替換為:

for source in "${parameters[@]}"; do
    if [ -r "$source" ]; then
        [[ ! -d "$dest/$(dirname $source)" ]] && mkdir -p "$dest/$(dirname $source)"
        find $(dirname $source) -name "$(basename $source)" -exec mv {} "$dest/$(dirname $source)" \; -delete
    else
        echo "$0: $source is not readable."
    fi
done

然而,由於這個東西依賴於一個很多關於 的值$PWD,我要求您在使用它時要非常小心。

相關內容