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_LINES
espaç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 echo
utilitá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 printf
over 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 find
executar grep
diretamente em tantos debug.log*
arquivos quanto possível por vez. Observe que se livrar de xargs
não resolve o problema das novas linhas, pois xargs
nã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.