$ ls *mp3 | xargs mplayer
Playing Lemon.
File not found: 'Lemon'
Playing Tree.mp3.
File not found: 'Tree.mp3'
Exiting... (End of file)
Mi comando falla porque el archivo "Lemon Tree.mp3" contiene espacios y xargs piensa que son dos archivos. ¿Puedo hacer que find + xargs funcione con nombres de archivo como este?
ls |grep mp3 |sed -n "7p"
solo puedes usarecho "Lemon Tree.mp3"
.Respuestas:
El
xargs
comando toma caracteres de espacio en blanco (tabulaciones, espacios, nuevas líneas) como delimitadores. Puede reducirlo solo para los nuevos caracteres de línea ('\ n') con una-d
opción como esta:Funciona solo con GNU xargs. Para sistemas BSD, use la
-0
opción como esta:Este método es más simple y también funciona con los xargs de GNU.
fuente
-E
, por ejemplo:xargs -E '\n'
La utilidad xargs lee cadenas delimitadas de espacio, tabulación, nueva línea y fin de archivo a partir de la entrada estándar y ejecuta la utilidad con las cadenas como argumentos.
Desea evitar usar el espacio como delimitador. Esto se puede hacer cambiando el delimitador para xargs. De acuerdo con el manual:
Como:
Para responder a la pregunta sobre la reproducción del séptimo mp3; es más simple correr
fuente
find
y GNUxargs
; no todas las versiones de esos programas son compatibles con esas opciones (aunque hay un caso que deberían hacer).find
con-print0
yxargs
con-0
. Sin embargo, AFAIK, HP-UX, AIX y Solaris no lo hacen (pero debo corregirlo: HP-UX 11i no; Solaris 10 no; AIX 5.x no; pero no son versiones actuales ) No sería difícil cambiarsed
, por ejemplo, usar 'líneas' que terminan en'\0'
lugar de'\n'
, y el POSIX 2008getdelim()
facilitaría la administración.Tratar
en vez de
fuente
xargs en MacOS no tiene la opción -d, por lo que esta solución usa -0 en su lugar.
Obtenga ls para generar un archivo por línea, luego traduzca las nuevas líneas en nulos y dígale a xargs que use nulos como delimitador:
ls -1 *mp3 | tr "\n" "\0" | xargs -0 mplayer
fuente
Esto ayudó en mi caso a eliminar diferentes archivos con espacios. Debería funcionar también con mplayer. El truco necesario son las citas. (Probado en Linux Xubuntu 14.04.)
fuente
La respuesta de Dick.Guertin [1] sugirió que uno podría escapar de los espacios en un nombre de archivo es una alternativa valiosa a otras soluciones sugeridas aquí (como usar un carácter nulo como separador en lugar de espacios en blanco). Pero podría ser más simple: realmente no necesitas un personaje único. Puede simplemente haber agregado los espacios escapados directamente:
Además, el grep solo es necesario si solo desea archivos con espacios en los nombres. Más genéricamente (p. Ej., Al procesar un lote de archivos, algunos de los cuales tienen espacios, otros no), simplemente omita el grep:
Entonces, por supuesto, el nombre del archivo puede tener otros espacios en blanco que no sean espacios en blanco (por ejemplo, una pestaña):
Eso supone que tiene un sed que admite -r (expresiones regulares extendidas) como GNU sed o versiones recientes de bsd sed (por ejemplo, FreeBSD que originalmente deletreaba la opción "-E" antes de FreeBSD 8 y admite tanto -r como -E para compatibilidad a través de FreeBSD 11 al menos). De lo contrario, puede usar una expresión de corchete de clase de caracteres regex básica e ingresar manualmente el espacio y los caracteres de tabulación en los
[]
delimitadores.[1] Esto quizás sea más apropiado como comentario o edición para esa respuesta, pero por el momento no tengo suficiente reputación para comentar y solo puedo sugerir ediciones. Dado que las últimas formas anteriores (sin el grep) alteran el comportamiento de la respuesta original de Dick.Guertin, una edición directa tal vez no sea apropiada de todos modos.
fuente
ls | grep mp3 | sed -n "7p" | xargs -i mplayer {}
Tenga en cuenta que en el comando anterior,
xargs
llamará demplayer
nuevo para cada archivo. Esto puede ser indeseable paramplayer
, pero puede estar bien para otros objetivos.fuente
mplayer
a llamar para cada archivo. Es importante si lo intentas, por ejemplo... | xargs -I{} mplayer -shuffle {}
: a pesar de esto, se reproducirá en un orden completamente determinista-shuffle
.xargs
se usa principalmente con comandos que aceptan una lista de nombres de archivo (ejemplo sencillo:)rm
, e intenta pasar tantos nombres de archivo como pueda caber en cada invocación, dividiéndose en múltiples invocaciones si es necesario. Puede ver la diferencia cuando usa un comando donde cada invocación es visible, comoecho
(el valor predeterminado):seq 0 100000 | xargs
imprime todos los números del 0 al 23695 (específicos de la plataforma, pero eso es lo que sucede en mi sistema) en la primera línea, al 45539 en la línea 2, etc. Y tiene razón, para la mayoría de los comandos, no importará.En macOS 10.12.x (Sierra), si tiene espacios en los nombres de archivos o subdirectorios, puede usar lo siguiente:
fuente
Depende de (a) qué tan vinculado está al número 7 en lugar de, por ejemplo, Limones, y (b) si alguno de los nombres de sus archivos contiene nuevas líneas (y si está dispuesto a cambiarles el nombre si lo tienen).
Hay muchas formas de lidiar con eso, pero algunas de ellas son:
El
read
bucle no funciona si los nombres de archivo contienen nuevas líneas; los otros funcionan correctamente incluso con líneas nuevas en los nombres (y mucho menos espacios). Por mi dinero, si tiene nombres de archivo que contienen una nueva línea, debe cambiar el nombre del archivo sin la nueva línea. El uso de comillas dobles alrededor del nombre del archivo es clave para que los bucles funcionen correctamente.Si tiene GNU
find
y GNUxargs
(o FreeBSD (* BSD?) O Mac OS X), también puede usar las opciones-print0
y-0
, como en:Esto funciona independientemente del contenido del nombre (los únicos dos caracteres que no pueden aparecer en un nombre de archivo son barra diagonal y NUL, y la barra diagonal no causa problemas en una ruta de archivo, por lo que usar NUL como delimitador de nombre cubre todo). Sin embargo, si necesita filtrar las primeras 6 entradas, necesita un programa que maneje 'líneas' terminadas por NUL en lugar de nueva línea ... y no estoy seguro de que haya alguna.
El primero es, con mucho, el más simple para el caso específico en cuestión; sin embargo, es posible que no se generalice para cubrir sus otros escenarios que aún no ha enumerado.
fuente
Sé que no estoy respondiendo la
xargs
pregunta directamente, pero vale la pena mencionarfind
la-exec
opción.Dado el siguiente sistema de archivos:
El comando find se puede hacer para manejar el espacio en Dream Theater y King's X. Entonces, para encontrar a los bateristas de cada banda usando grep:
En la
-exec
opción se{}
encuentra el nombre del archivo, incluida la ruta. Tenga en cuenta que no tiene que escapar o ponerlo entre comillas.La diferencia entre
-exec
los terminadores (+
y\;
) es que+
agrupa tantos nombres de archivos como puede en una línea de comando. Mientras\;
que ejecutará el comando para cada nombre de archivo.Entonces,
find bands/ -type f -exec grep Drums {} +
resultará en:y
find bands/ -type f -exec grep Drums {} \;
dará como resultado:En el caso de que
grep
esto tenga el efecto secundario de imprimir el nombre del archivo o no.Por supuesto,
grep
las opciones-h
y-H
controlarán si el nombre del archivo se imprime o no, independientemente de cómogrep
se llame.xargs
xargs
También puede controlar cómo están los archivos man en la línea de comandos.xargs
por defecto agrupa todos los argumentos en una línea. Para hacer lo mismo que-exec \;
sí usaxargs -l
. Tenga en cuenta que la-t
opción le dicexargs
que imprima el comando antes de ejecutarlo.Ver que el
-l
opción le dice a xargs que ejecute grep para cada nombre de archivo.Contra el valor predeterminado (es decir, sin
-l
opción):xargs
tiene un mejor control sobre cuántos archivos pueden estar en la línea de comando. Dé a la-l
opción el número máximo de archivos por comando.Ver que
grep
se ejecutó con dos nombres de archivo debido a-l2
.fuente
Dado el título específico de esta publicación, aquí está mi sugerencia:
La idea es convertir espacios en blanco a cualquier carácter único, como '<', y luego cambiarlo a '\', una barra invertida seguida de un espacio en blanco. Luego puede canalizar eso en cualquier comando que desee, como:
La clave aquí radica en los comandos 'tr' y 'sed'; y puedes usar cualquier carácter además de '<', como '?' o incluso un tabulador.
fuente
tr
? ¿Por qué no solols *.mp3 | sed -n '7!b;s/\([[:space:]]\)/\\\1/g;p'
?Las soluciones alternativas pueden ser útiles ...
También puede agregar un carácter nulo al final de sus líneas usando Perl, luego use la
-0
opción en xargs. A diferencia de xargs -d '\ n' (en respuesta aprobada), esto funciona en todas partes, incluido OS X.Por ejemplo, para enumerar recursivamente (ejecutar, mover, etc.) archivos MPEG3 que pueden contener espacios u otros caracteres divertidos, usaría:
(Nota: para el filtrado, prefiero la sintaxis "| grep" más fácil de recordar que los argumentos de "find" --name).
fuente