Mueva un grupo de archivos, solicitando al usuario la confirmación de cada archivo

9

Sistema: Ubuntu MATE 18.04.

Tengo una colección de archivos (en varios directorios en una estructura de directorio) y quiero mover muchos de ellos a otro directorio. Puedo decir qué archivos quiero mover por sus nombres (son títulos de recetas), pero no hay otra forma de distinguir entre los archivos que quiero mover y los archivos que no quiero mover; Necesito tomar una decisión para cada archivo examinando el nombre yo mismo.

Entonces, estoy ejecutando un comando una vez para cada archivo que quiero mover, como

mv Snacks/OkaraCrackers NeedsTesting/
mv Snacks/SunflowerBrittle NeedsTesting/
mv Treats/ChocolateChilliFudge NeedsTesting/
mv Treats/PecanBlondies NeedsTesting/

Incluso con la finalización de pestañas, esto es demasiado escribir. Lo que realmente quiero hacer es algo como

shopt -s globstar
mv --prompt-me-for-every-file ** NeedsTesting/

Entonces solo puedo presionar yo npara cada archivo.

¿Cómo puedo mover un grupo de archivos y solicitar una confirmación para cada archivo?

Zanna
fuente

Respuestas:

6

Forma 1: en su navegador de archivos gráficos, usando una vista de árbol

Supongo que su objetivo real es hacer una elección para cada archivo, y no estrictamente hablando para que se le solicite . Sin embargo, si prefiere que se le pregunte acerca de cada archivo en un terminal, consulte el Modo 2 a continuación.

La mayoría de los exploradores de archivos gráficos admiten una vista de árbol donde puede ver múltiples niveles de una jerarquía de directorios juntos. Puede copiar o mover archivos fuera de esta vista, ya sea individualmente o seleccionándolos y luego operando en toda la selección. Esto funciona incluso con archivos de varias carpetas.

En algunos navegadores de archivos, uno debe ir al menú de Preferencias para habilitar la vista de árbol. En Caja, el navegador de archivos MATE, siempre está habilitado en la vista de lista. Haga clic en Ver → Lista (o presione Ctrl+ 2) para cambiar a la vista de lista. Cada directorio tiene un pequeño triángulo que mira hacia la derecha a la izquierda, lo que indica que se puede expandir. Para expandir una carpeta, haga clic en ese triángulo o presione la tecla (flecha derecha) cuando se selecciona la carpeta. En este ejemplo, los he seleccionado todos uno por uno y los estoy arrastrando a la vez a su destino:

múltiples archivos seleccionados en una estructura de árbol en el buscador de archivos de Caja, siendo arrastrados a otra carpeta pero aún no movidos

Suponiendo que el origen y el destino están en la misma unidad, arrastra los movimientos de forma predeterminada. Si quisiera copiar en su lugar, mantenga presionada la Ctrltecla.

la situación después de que se haya completado el movimiento de arrastre, en el que los archivos que se seleccionaron ahora están todos juntos en la carpeta de destino en lugar de sus ubicaciones separadas originales

En teoría, es fácil corregir los errores al usar este método, porque la mayoría de los exploradores de archivos (incluida Caja) admiten Ctrl+ Zpara deshacer acciones recientes, incluidas acciones por lotes. Sin embargo, he tenido suerte con eso. A veces los archivos vuelven a la carpeta incorrecta.

La buena noticia es que parece estar trabajando principalmente con documentos de texto, que tienden a ser pequeños, por lo que puede hacer una copia de seguridad adicional con el tarprimero sin mucha molestia. Sugiero hacer eso independientemente del método que utilice.

Camino 2 : el findcomando con la -okacción

Es de uso común findencontrar archivos y pasar sus rutas a un comando externo arbitrario con las acciones -execy -execdir. Pero findtambién tiene -oky -okdirese aviso antes de cada vez que ejecutan un comando. Si realmente desea que se le solicite en un terminal sobre cada archivo, creo que este es el camino a seguir.

Cuando se hace para producir los mismos efectos que se muestran arriba, se ve así:

ek@Gnar:~$ find Texts -xtype f -ok mv -t 'Glorious Destination Folder' {} \;
< mv ... Texts/Robert Frost/New Hampshire.pdf > ? y
< mv ... Texts/Robert Frost/In The Clearing.pdf > ? n
< mv ... Texts/Helen Keller/The Story of My Life.pdf > ? y
< mv ... Texts/Saki/The Short Stories of Saki.pdf > ? y
< mv ... Texts/Jane Austen/Sense and Sensibility.pdf > ? n
< mv ... Texts/Jane Austen/Pride and Prejudice.pdf > ? y
< mv ... Texts/Richard Connell/The Stolen Crime.pdf > ? n
< mv ... Texts/Richard Connell/The Most Dangerous Game.txt > ? y
< mv ... Texts/Mary Wollstonecraft Shelley/Mathilda.epub > ? n
< mv ... Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf > ? y
< mv ... Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf > ? n
< mv ... Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm > ? y

Reemplace Textscon el directorio de origen (que podría ser solo .si lo desea cd) y Glorious Destination Foldercon el directorio de destino real.

Esto ejecuta un comando por archivo; a diferencia de -execy -execdir, -oky -okdirno admite +en lugar de \;pasar múltiples rutas encontradas en la misma invocación de un comando. En consecuencia, no necesita usar la -t destforma de mv. Sugiero hacerlo de todos modos, sin embargo, tanto en general con findy particularmente en esta situación por lo que las indicaciones se parecen más a los comandos que provocó que están alrededor.

A medida que se escribe ese comando, si findencuentra un enlace simbólico que finalmente apunta a un archivo normal, se mueve (el enlace, no el objetivo) en lugar de ignorarlo. Si realmente desea operar solo un archivo normal, use en -type flugar de -xtype f.

Es posible que desee hacer esto en una scriptsesión para poder descubrir qué sucedió si comete un error. Pero, de nuevo, no hay razón para no tener una copia de seguridad.

Camino 3: generar un manifiesto y editarlo

Al menos mientras los archivos no tengan nuevas líneas en sus nombres, puede comenzar usando un findcomando simple para generar un manifiesto: un archivo que enumera los nombres de los archivos que le interesan (en este caso potencialmente) :

find Texts -xtype f >manifest

Reemplácelo manifestcon el nombre que desee para el archivo que enumera los archivos en consideración (y ajuste las instrucciones restantes en consecuencia).

Como arriba, reemplace Textscon su directorio de origen real, que podría ser .si lo hubiera cdhecho. Sin embargo, si Textses una ruta relativa (incluso si es .), entonces debe asegurarse de estar en la misma ubicación más adelante cuando realice los movimientos.

Después de ejecutar ese findcomando, ábralo manifesten un editor de texto. Esto podría ser nano, vim, emacs, gedit, pluma, etc. En el editor, comente las líneas que nombres de los archivos que no desea mover colocando una #al comienzo de ellos. Algunos editores resaltarán esas líneas de manera diferente incluso cuando no reconozca que su archivo tiene ningún formato que sepa que tiene comentarios. Sin embargo, la mayoría no lo hará, y la verdadera razón por la que sugiero hacerlo de esta manera es que usted, como humano, es probable que tenga experiencia comentando líneas en los archivos de configuración (y tal vez en el código fuente). Creo que esto es más intuitivo y menos propenso a errores, de lo que sería para marcar las líneas que no desea mover.

Por supuesto, podría simplemente eliminar las líneas de los archivos que no desea mover. La ventaja de comentarlos es que más tarde quedará claro lo que hiciste.

En mi ejemplo, así es como se ve el contenido del archivo después de editarlo:

Texts/Robert Frost/New Hampshire.pdf
# Texts/Robert Frost/In The Clearing.pdf
Texts/Helen Keller/The Story of My Life.pdf
Texts/Saki/The Short Stories of Saki.pdf
# Texts/Jane Austen/Sense and Sensibility.pdf
Texts/Jane Austen/Pride and Prejudice.pdf
# Texts/Richard Connell/The Stolen Crime.pdf
Texts/Richard Connell/The Most Dangerous Game.txt
# Texts/Mary Wollstonecraft Shelley/Mathilda.epub
Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf
# Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf
Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm

Luego puede filtrar las líneas comentadas con grepy canalizar el resultado xargspara pasarlas a mv:

grep -Pv '^\s*#' manifest | xargs -d '\n' mv -t 'Glorious Destination Folder'

Como arriba, reemplace Glorious Destination Foldercon el nombre del destino real. Eso es; tus archivos son movidos Por supuesto, puede escribir echoantes mvpara ver los comandos que se ejecutarán primero, si lo desea.

La forma en que funciona ese comando es:

  1. El grepcomando genera líneas desde manifestque no ( -v) comienzan ( ^) con un *espacio en blanco opcional ( \s) seguido de un #carácter literal . La -Pbandera selecciona PCRE como el dialecto de las expresiones regulares (lo que permite \sque considero más legible que el tradicional [[:space:]]).
  2. El xargscomando divide su entrada (que es la salida de grep) en campos terminados en nueva línea ( -d '\n'), luego pega cada campo (sin la nueva línea de terminación) como un argumento separado al final del comando mv -t 'Glorious Destination Folder', que ejecuta.
Eliah Kagan
fuente
1
-okEn mi humilde opinión la mejor respuesta
pim
7

Aquí hay un pequeño script ( mv-confirm.sh):

#!/bin/bash

# Just make sure there are at least one source and one destination
if [ "$#" -lt 2 ]; then
    echo "Illegal number of parameters"
fi

DESTINATION=${*:$#}             # last argument
SOURCES=( ${@:1:$#-1} )         # all but last arguments

for i in "${SOURCES[@]}"
do
    read -p "move '$i' to '$DESTINATION' ? [y/n] " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
        echo mv "$i" "$DESTINATION"
    fi
done

Uso de la muestra:

./mv-confirm.sh ** somewhere
move 'a' to 'somewhere' ? [y/n] n
move 'b' to 'somewhere' ? [y/n] y
mv b d
...

no olvide hacer que el script sea ejecutable ( chmod +x mv-confirm.sh).

nótese bien

Como no quiero meterme con sus archivos, agregué echoantes del mv comando real . Siéntase libre de eliminarlo para mover realmente los archivos.

pim
fuente