Combina xargs -I con sed

Combina xargs -I con sed

Quiero usar buscar para buscar ciertos archivos y luego usar xargs con cp y sed para mover estos archivos a otra carpeta y cambiarles el nombre. Sé cómo hacer esto en bucle, pero eso no es lo que estoy buscando.

Lo intenté:

find ${FOLDER} -iname "*${SOME_STRING}*" | xargs -I {} cp {} $(echo {} | sed 's/ABC/XYZ/g')

¿Por qué esto no funciona y cuál sería una solución?

Respuesta1

Prueba esto. No necesita xargs, solo findy . No cambiará ningún archivo, perosedcopyvoluntadimprima una lista de comandos de shell para copiar los archivos. Entonces, si le gustan los comandos que imprime, ejecútelo nuevamente y elimine el #antes sh -xde la última línea y deje que el shell ejecute los comandos.

find "${FOLDER:-.}" -iname "*${SOME_STRING:-ABC}*" |
sed "
    s/^/'/                      # surround filename with single quotes
    s/$/'/
    h                           # save filename in the sed hold space
    s/ABC/XYZ/g                 # change filename
    H                           # append to hold space (separates with newline)
    g                           # get original and modified from hold
    s/\n/ /g                    # replace the newline with a space
    s/^/cp -i/                  # make it into a copy command
"  #| sh -x                     # optionally pipe to shell

¿Por qué este enfoque es mejor que xargsen este caso? Porque este método inicia solo 3 procesos en total ( find, sedy sh) además del cpcomando requerido para cada archivo.

Para usar xargs, procesar cada nombre de archivo requeriría más procesos que el único cpcomando requerido.

Es mucho más eficiente dejar que se genere la invocación de sedtodode los cpcomandos, que invocar un nuevo sedproceso para cada nombre de archivo.

Respuesta2

Usando GNU Parallel se ve así:

find ${FOLDER} -iname "*${SOME_STRING}*" |
  parallel cp {} '{= s/ABC/XYZ/g =}'

La construcción {= =} contiene una expresión Perl que cambia $_.

Una de las ventajas es que GNU Parallel hace lo correcto incluso si tiene archivos llamados:

My brother's 12" records worth >100$.txt

o horrores como:

touch Y-"$(perl -e 'print pack("c*",1..9,11..46,48..255)')"

información relacionada