Для вашей второй формы:
sed -n '/test1/,/test2/p' file.txt | xargs > newfile.txt ; sed 's/test2/&\n/g' newfile.txt | sed -e 's/^[ \t]*//'
Con sed
, POSIXly:
var=$(
ps -Ao args= | sed -n 's|.* -h:\(.*\)/component_events\.xml.*|\1|p'
)
En efecto, eso devuelve la parte de la línea de comando entre la última aparición de /component_events.xml
y la última aparición antes de -h:
.
Entonces, si la línea de comando fuera:
... -h:x/component_events.xml -g:y/component_events.xml
Obtendrías x/components_events.xml -g:y
en lugar de x
.
Podría cambiarlo a sed -n 's|.* -h:\([^ ]*\)/component_events\.xml.*|\1|p'
para evitar eso, pero eso ya no sería así para los nombres de directorio que contienen caracteres de espacio.
En un sistema GNU/Linux reciente, también podría hacer:
LC_ALL=C grep -zhPo '^-h:\K.*(?=/component_events\.xml)' /proc/*/cmdline |
tr '\0' '\n'
Lo que funcionaría para cualquier nombre de directorio.
Usando pgrep
para encontrar el pid y/proc/$PID/cmdline
:
var=$(
pgrep -f "component_events.xml" | \
xargs -I{} sh -c "head -z -n1 /proc/{}/cmdline | tr '\0' '\n'" | \
xargs -n1 dirname
)
Esto también funciona cuando la ruta del comando tiene argumentos y cuando se encontraron varios PID.
Explicación:
Búsqueda de PID:
pgrep -f "component_events.xml"
Para cada PID encontrado, obtenga el comando completo (/proc/PID/cmdline
), pero imprima solo el comando sin argumentos(head -z -n1
).
xargs -I{} sh -c "head -z -n1 /proc/{}/cmdline
Luego reemplace el final \0
con nueva línea(\n
):
tr '\0' '\n'"
Muestra solo el nombre de directorio:
xargs -n1 dirname