¿Cómo usar grep y mv juntos en un directorio en Shell?

¿Cómo usar grep y mv juntos en un directorio en Shell?

¿Cómo se recopila el contenido de todos los archivos en un directorio para "PRUEBA" y luego se mueven esos archivos a un directorio diferente (como el directorio de inicio)?

Respuesta1

Puedes combinargrepyencontrarpara esta tarea:

find SOURCE -maxdepth 1 -type f -exec grep -q TEST {} \; -exec mv -i {} DEST \;

Cómo funciona

  • find SOURCE -maxdepth 1 -type fencuentra todos los archivos ( -type f) en el directorioFUENTE.

    Si también desea incluir archivos en subdirectorios, simplemente elimine -maxdepth 1.

  • -exec grep -q TEST {} \;greps los archivos, uno por uno, para la cadenaPRUEBA. Aquí {}está el archivo que se está procesando actualmente.

    El -qmodificador hace que grep sea "silencioso", es decir, no generará nada. La -execafirmación será verdadera sigreptiene éxito, es decir, encuentra la cadena.

  • -exec mv -i {} DEST \;mueve un archivo que contiene la cadenaPRUEBAen el directorioDESTINO.

    El -iinterruptor hacemv"interactivo", es decir, avisará antes de sobrescribir otros archivos.

Respuesta2

Sólo otra alternativa (aunque esto requiere algunas extensiones específicas de GNU; como etiquetó la pregunta "Unix", es posible que no le convenga):

grep -lZd skip TEST SOURCE/* | xargs -0I{} mv -i {} DEST
  • grep -l

    imprime nombres de archivos coincidentes en lugar de la salida normal.

  • grep -Z

    proporciona una salida separada por bytes nulos, lo cual es una apuesta segura al manejar nombres de archivos extraños a través de tuberías.

  • grep -d skip

    define la skipacción para los directorios encontrados entre los argumentos de entrada.

    Esto realmente no es necesario; simplemente evita el aviso grep: SOURCE/DIR: Is a directorycuando encuentra directorios. Si desea una lectura recursiva de archivos en directorios, use la acción recurse, o incluso más brevemente, simplemente el -rinterruptor equivalente (consulte también el punto a continuación).

  • SOURCE/*

    coincide con todos los archivos en el directorio SOURCEusando shellglobo. Los archivos ocultos no coinciden por defecto; esto se puede cambiar configurándolo shopt -s dotgloben Bash antes de grepemitir el comando.

    Uno podría verse tentado a simplemente agregar SOURCE/.*argumentos a los de entrada, pero esto quizás tendrá consecuencias inesperadas si se usa con -r(ya que coincidimos .y ..también).

    Si desea una coincidencia recursiva, simplemente utilícela -r SOURCEsin globbing de archivos como argumento de entrada, que incluye archivos ocultos en la estructura del directorio.

  • xargs -0

    interpreta la entrada como separada por nulos.

  • xargs -I{}

    define {}como un marcador de posición para el argumento de entrada.

  • mv -i

    hace que el movimiento sea interactivo según la sugerencia de Dennis, para evitar errores.

Para probar este patrón (o comandos en general), una técnica útil es insertar echoantes del comando real para ver qué comandos se van a ejecutar, es decir, cambiar mva echo mv.

Respuesta3

$ mv PRUEBA* /ruta/al/destino

Funciona para mí, espero que funcione para ti. En mi caso fue:

$ mv nota_[5,6]* ~/documentos/notas

Lo que movió note_5_math.pdf y note_6_math.pdf al directorio inicio/documentos/notas.

información relacionada