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 whee
cederáwhee foo bar baz bat
. ¿Quizás agregar las opciones-L
o-n
?La respuesta aceptada tiene la idea correcta, pero la clave es pasar
xargs
el-n1
interruptor, 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
cat
completo y simplemente ir con:fuente
xargs
que no se ejecutará sistdin
está 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 -r
lee una sola línea desde la entrada estándar (read
sin-r
interpretar 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; done
no funcionó. Funcionó con un archivo entubado en elwhile
bucle, funcionó solo contail -f
, funcionó con sologrep
, pero no con ambas tuberías. Dando a lagrep
de la--line-buffered
opción que hizo el trabajocommand | while read -r line; do echo "$line" | command ; done
Estoy 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 -0
utiliza 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
cat
aquí, ya quegrep
puede leer directamente el archivo< stuff grep pattern
perogrep pattern stuff
no 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 read
realice 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.
read
no toma-r
argumentos, 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.command
en 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
while
necesita ser emparejado condo
& endone
lugar 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_folder
que 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
.html
archivo agregando una.bak
extensión:Desde la
xargs
página del manual para MacOS / BSD :xargs
Pá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
vim
y 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 hlsearch
es ú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
\n
en 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