Quiero ejecutar un comando java una vez por cada partido de ls | grep pattern -. En este caso, creo que podría hacerlo, find pattern -exec java MyProg '{}' \;pero tengo curiosidad sobre el caso general: ¿hay una manera fácil de decir "ejecutar un comando una vez por cada línea de entrada estándar"? (En pescado o golpe)
                162
            
  
            
printf "foo bar\nbaz bat" | xargs echo wheecederáwhee foo bar baz bat. ¿Quizás agregar las opciones-Lo-n?La respuesta aceptada tiene la idea correcta, pero la clave es pasar
xargsel-n1interruptor, lo que significa "Ejecutar el comando una vez por línea de salida:"O, para un solo archivo de entrada, puede evitar la tubería por
catcompleto y simplemente ir con:fuente
xargsque no se ejecutará sistdinestá vacía:--no-run-if-empty-r: si la entrada estándar no contiene ningún Sin espacios, no se ejecuta el comando. Normalmente, el comando se ejecuta una vez incluso si no hay entrada. Esta opción es una extensión GNU.command?En Bash o cualquier otro shell de estilo Bourne (ash, ksh, zsh, ...):
read -rlee una sola línea desde la entrada estándar (readsin-rinterpretar barras invertidas, no quiere eso). Por lo tanto, puede hacer lo siguiente:fuente
tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; doneno funcionó. Funcionó con un archivo entubado en elwhilebucle, funcionó solo contail -f, funcionó con sologrep, pero no con ambas tuberías. Dando a lagrepde la--line-bufferedopción que hizo el trabajocommand | while read -r line; do echo "$line" | command ; doneEstoy de acuerdo con Keith, xargs es la herramienta más general para el trabajo.
Usualmente uso un enfoque de 3 pasos.
Hay formas más pequeñas y rápidas, pero estas formas casi siempre funcionan.
Un simple ejemplo:
las 2 primeras líneas seleccionan algunos archivos para trabajar, luego awk prepara una buena cadena con un comando para ejecutar y algunos argumentos y $ 1 es la entrada de la primera columna de la tubería. Y finalmente me aseguro de que xargs envíe esta cadena a bash que solo la ejecute.
Es un poco exagerado, pero esta receta me ha ayudado en muchos lugares ya que es muy flexible.
fuente
xargs -0utiliza el byte nulo como separador de registros, por lo que su declaración de impresión awk debería serprintf("MyJavaProg --args \"%s\"\0",$1)awk, puedes hacer que coincida con el patrón y omitirgrep, por ejemplo,ls | awk '/xls/ {print...GNU Parallel está hecho para ese tipo de tareas. El uso más simple es:
Mire el video de introducción para obtener más información: http://www.youtube.com/watch?v=OpaiGYxkSuQ
fuente
cataquí, ya quegreppuede leer directamente el archivo< stuff grep patternperogrep pattern stuffno requiere redirección o gato. Aún así, eso no cambia materialmente su argumento y si cree que es más claro usar siempre las cosas en una tubería que comienzacat, entonces el poder para ustedAdemás,
while readrealice un bucle en la concha de pescado (supongo que quiere la concha de pescado, teniendo en cuenta que usó la etiqueta de pescado ).Pocos puntos a tener en cuenta.
readno toma-rargumentos, y no interpreta las barras diagonales inversas, para facilitar el uso más común de los casos de uso.$line, ya que a diferencia de bash, fish no separa las variables por espacios.commanden sí mismo es un error de sintaxis (para detectar el uso de argumentos de marcador de posición). Reemplácelo con el comando real.fuente
whilenecesita ser emparejado condo& endonelugar deend?Si necesita controlar dónde se inserta exactamente el argumento de entrada en su línea de comando o si necesita repetirlo varias veces, debe usarlo
EJEMPLO 1xargs -I{}.Cree una estructura de carpetas vacía
EJEMPLO # 2another_folderque refleje las subcarpetas en el directorio actual:Aplique una operación en una lista de archivos proveniente de stdin, en este caso haga una copia de cada
.htmlarchivo agregando una.bakextensión:Desde la
xargspágina del manual para MacOS / BSD :xargsPágina del manual de Linux :fuente
Cuando se trata de entradas potencialmente no higienizadas, me gusta ver todo el trabajo 'enunciado' línea por línea para una inspección visual antes de ejecutarlo (especialmente cuando es algo destructivo como limpiar los buzones de las personas).
Entonces, lo que hago es generar una lista de parámetros (es decir, nombres de usuario), alimentarlo a un archivo en un registro por línea, de esta manera:
Luego abro la lista
vimy la destruyo con expresiones de búsqueda y reemplazo hasta que obtengo una lista de comandos completos que deben ejecutarse, así:De esta manera, si su expresión regular está incompleta, verá en qué comando tendrá problemas potenciales (es decir
/bin/rm -fr johnnyo connor). De esta manera, puede deshacer su expresión regular y volver a intentarlo con una versión más confiable. El cambio de nombre es conocido por esto, porque es difícil ocuparse de todos los casos extremos como Van Gogh, O'Connors, St. Clair, Smith-Wesson.Tener
set hlsearches útil para hacer estovim, ya que resaltará todas las coincidencias, por lo que puede detectar fácilmente si no coincide o coincide de manera no intencionada.Una vez que su expresión regular es perfecta y detecta todos los casos en los que puede probar / pensar, generalmente la convierto en una expresión sed para que pueda automatizarse completamente para otra ejecución.
Para los casos en que el número de líneas de entrada le impide realizar una inspección visual, le recomiendo hacer eco del comando en la pantalla (o mejor aún, un registro) antes de que se ejecute, por lo que si se produce un error, sabrá exactamente qué comando causó que falle Luego puede volver a su expresión regular original y ajustar una vez más.
fuente
Si un programa ignora la canalización pero acepta archivos como argumentos, puede simplemente señalarlo al archivo especial
/dev/stdin.No estoy familiarizado con Java, pero aquí hay un ejemplo de cómo lo haría para bash:
El $ es necesario para que bash se traduzca
\nen nuevas líneas. No estoy seguro de por qué.fuente
Prefiero esto: permitir comandos de varias líneas y código claro
ref https://stackoverflow.com/a/3891678/248616
fuente
Aquí, una copia que puedes usar de inmediato:
El elemento de la lista se colocará donde está el {} y el resto del comando y los parámetros se usarán tal cual.
fuente