¿Jerarquía de directorios mv y cp?

¿Jerarquía de directorios mv y cp?

¿Puedo también mover o copiar la jerarquía de directorios de un archivo cuando yo mvo cpel archivo?

Por ejemplo, si soy yo mvo cp dir1/dir2/fileen otro lugar, solo será mvo cp file. ¿Qué pasa si quiero también mvo cp dir1/dir2? En lugar de mkdir -p dir1/dir2, ¿se puede hacer con un solo comando?

Respuesta1

Puedes usar el interruptor cpde :--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, sin embargo, no tiene un --parentsinterruptor, pero podrías hacer algo como:

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

Que lo hará:

  • Encuentra el archivo.
  • Cópialo (junto con sus padres) al destino.
  • Eliminar el original.

Podrías crear una función para esto:

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/

Sin embargo, esto puede requerir algunos ajustes si intentas mover varios archivos. Aquí hay un ejemplo (funciona en bash, pero no hay garantías para otros shells):

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
}

Bueno... es un poco más largo de lo que esperaba pero debería funcionar.

Editar: comoSebastián PiechComo se señaló en un comentario, confiar en cphacer mvel trabajo es un gran factor de destrucción del rendimiento, ya que mvoriginalmente no es necesarioCopiarel archivo, simplemente edite sus metadatos. Es posible que desees reemplazar el bucle anterior con:

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

Sin embargo, dado que esto depende de unloteEn cuanto al valor de $PWD, le pediría que tenga mucho cuidado si lo utiliza.

información relacionada