Como reter novas linhas em xargs -I {}

Como reter novas linhas em xargs -I {}

O seguinte extrai algumas dezenas de linhas em uma variável, mas de alguma forma elas são todas colocadas juntas em uma única linha. Ou seja, eles perdem o caractere de nova linha original:

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

Existe uma maneira de manter o caractere de nova linha em uma instrução como a acima?

Responder1

Se você estiver testando isso com

echo $ALL_FOUND_LINES

então não estou surpreso que todas as novas linhas tenham desaparecido, já que o shell dividiria o valor em $ALL_FOUND_LINESespaços, tabulações e novas linhas (por padrão) em palavras (e então expandiria ainda mais cada palavra por meio da geração de nome de arquivo (globbing)). Isso acontece porque a expansão não está entre aspas. O echoutilitário então obtém uma lista de palavras que imprime em uma única linha.

Um teste melhor seria

printf '%s\n' "$ALL_FOUND_LINES"

Observe a citação da expansão variável. Para a escolha de printfover echo, consultePor que printf é melhor que echo?.


Seu comando pode ser melhorado em

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

Aqui, em vez de passar os nomes dos arquivos para xargs, deixamos findexecutar grepdiretamente em tantos debug.log*arquivos quanto possível por vez. Observe que se livrar de xargsnão resolve o problema das novas linhas, pois xargsnão tem nada a ver com isso. Isso aceleraria um pouco as coisas, pois envolve menos invocações de grep.

Veja tambémCompreendendo a opção -exec de `find`.

Se você precisar fazer algo com cada uma das linhas encontradas, você pode fazer um loop sobre elas assim:

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

(ou substitua o loop while por qualquer outra etapa de processamento que você precise realizar). Portanto, nunca há necessidade de armazenar todos os dados em uma variável como uma string delimitada por nova linha.

Veja tambémCompreendendo "IFS = read -r line"

Responder2

homem 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.

informação relacionada