Cómo conservar nuevas líneas en xargs -I {}

Cómo conservar nuevas líneas en xargs -I {}

Lo siguiente extrae algunas docenas de líneas en una variable, pero de alguna manera se colocan todas juntas en una sola línea. Es decir, pierden el carácter de nueva línea original:

ALL_FOUND_LINES=$(find "$TEMP" -type f -name "debug.log*" | xargs -I {} grep -F "STARTING HOST " {})

¿Hay alguna manera de conservar el carácter de nueva línea en una declaración como la anterior?

Respuesta1

Si estás probando esto con

echo $ALL_FOUND_LINES

entonces no me sorprende que todas las nuevas líneas desaparezcan, ya que el Shell dividiría el valor en $ALL_FOUND_LINESespacios, tabulaciones y nuevas líneas (de forma predeterminada) en palabras (y luego expandiría aún más cada palabra mediante la generación de nombres de archivos (globbing)). Lo hace ya que la expansión no está citada. Luego, la echoutilidad obtiene una lista de palabras que imprime en una sola línea.

Una mejor prueba sería

printf '%s\n' "$ALL_FOUND_LINES"

Tenga en cuenta la cita de la expansión variable. Para elegir printfmás echo, consulte¿Por qué printf es mejor que echo?.


Tu comando se puede mejorar en

find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} +

Aquí, en lugar de pasar los nombres de los archivos a xargs, permitimos que findse ejecuten grepdirectamente en tantos debug.log*archivos como sea posible a la vez. Tenga en cuenta que deshacerse de xargsno resuelve el problema de las nuevas líneas, ya que xargsno tiene nada que ver con esto. Esto aceleraría un poco las cosas ya que implica menos invocaciones de grep.

Ver tambiénComprender la opción -exec de "buscar".

Si necesita hacer algo con cada una de las líneas encontradas, puede recorrerlas de esta manera:

find "$TEMP" -type f -name 'debug.log*' -exec grep -h -F 'STARTING HOST ' {} + |
while IFS= read -r line; do
    # use "$line" here (with quotes)
done

(o reemplace el bucle while con cualquier otro paso de procesamiento que necesite realizar). Por lo tanto, nunca es necesario almacenar todos los datos en una variable como una cadena delimitada por nueva línea.

Ver tambiénEntendiendo "IFS= leer -r línea"

Respuesta2

hombre xargs

   -L max-lines
          Use at most max-lines nonblank input  lines  per  command  line.
          Trailing blanks cause an input line to be logically continued on
          the next input line.  Implies -x.

   -l[max-lines], --max-lines[=max-lines]
          Synonym for the -L option.  Unlike -L, the max-lines argument is
          optional.   If  max-lines  is not specified, it defaults to one.
          The -l option is deprecated since the POSIX  standard  specifies
          -L instead.

información relacionada