Quando executo comandos no Bash (ou para ser específico wc -l < log.txt), a saída contém uma quebra de linha após ela. Como faço para me livrar dele?
Quando executo comandos no Bash (ou para ser específico wc -l < log.txt), a saída contém uma quebra de linha após ela. Como faço para me livrar dele?
Respostas:
Se a saída esperada for uma única linha , você poderá simplesmente remover todos os caracteres de nova linha da saída. Não seria incomum canalizar para o utilitário 'tr' ou para Perl, se preferir:
wc -l < log.txt | tr -d '\n'
wc -l < log.txt | perl -pe 'chomp'
Você também pode usar a substituição de comando para remover a nova linha à direita:
echo -n "$(wc -l < log.txt)"
printf "%s" "$(wc -l < log.txt)"
Observe que não concordo com a decisão do OP de escolher a resposta aceita. Eu acredito que se deve evitar o uso de 'xargs' sempre que possível. Sim, é um brinquedo legal. Não, você não precisa aqui.
Se a saída esperada puder conter várias linhas , você terá outra decisão a tomar:
Se você deseja remover vários caracteres de nova linha do final do arquivo, use novamente a substituição do cmd:
printf "%s" "$(< log.txt)"
Se você deseja remover estritamente o último caractere de nova linha de um arquivo, use Perl:
perl -pe 'chomp if eof' log.txt
Note que se você tem certeza de que possui um caractere de nova linha à direita que deseja remover, você pode usar 'head' dos coreutils do GNU para selecionar tudo, exceto o último byte. Isso deve ser bem rápido:
head -c -1 log.txt
Além disso, para garantir a integridade, você pode verificar rapidamente onde seus caracteres de nova linha (ou outros caracteres especiais) estão em seu arquivo usando 'cat' e o sinalizador 'show-all'. O caractere do cifrão indicará o final de cada linha:
cat -A log.txt
tr --delete '\n'.
| tr -d '\r'
Mão única:
wc -l < log.txt | xargs echo -n
echo -n `wc -l log.txt`
IFS) em um espaço. Exemplo echo "a b" | xargs echo -n:; echo -n $(echo "a b"). Isso pode ou não ser um problema para o caso de uso.
-e, ela será interpretada como a opção para echo. É sempre mais seguro de usar printf '%s'.
xargsé muito lento no meu sistema (e suspeito que também esteja em outros sistemas), então printf '%s' $(wc -l log.txt)pode ser mais rápido, pois printfgeralmente é um componente interno (também porque não há redirecionamento de informações). Nunca use backticks, eles foram descontinuados nas versões mais recentes do POSIX e apresentam inúmeras desvantagens.
Também há suporte direto para remoção de espaços em branco na substituição de variáveis do Bash :
testvar=$(wc -l < log.txt)
trailing_space_removed=${testvar%%[[:space:]]}
leading_space_removed=${testvar##[[:space:]]}
trailing_linebreak_removed=${testvar%?}
Se você atribuir sua saída a uma variável, bashremove automaticamente os espaços em branco:
linecount=`wc -l < log.txt`
printf já recorta a nova linha à direita para você:
$ printf '%s' $(wc -l < log.txt)
Detalhe:
%smarcador de posição da cadeia. %s\n), isso não acontecerá."$(command)", as novas linhas internas serão preservadas - e somente a nova linha à direita será removida. O shell está fazendo todo o trabalho aqui - printfé apenas uma maneira de direcionar os resultados da substituição de comando para stdout.
$( )construção. Aqui está a prova:printf "%s" "$(perl -e 'print "\n"')"
$ printf '%s' "$(wc -l < log.txt)"
Se você deseja remover apenas a última nova linha , passe por:
sed -z '$ s/\n$//'
sednão adicionará um \0ao final do fluxo se o delimitador estiver definido como NULvia -z, enquanto que para criar um arquivo de texto POSIX (definido para terminar em a \n), ele sempre produzirá um final \nsem -z.
Por exemplo:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender
E para provar que não foi NULadicionado:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72 foo.bar
Para remover várias linhas novas à direita , passe por:
sed -Ez '$ s/\n+$//'
sednão fornece -z.
Se você quiser imprimir qualquer coisa no Bash sem fim de linha, faça o eco com a -nchave.
Se você já tiver uma variável, faça o eco com a nova linha à direita cortada:
$ testvar=$(wc -l < log.txt)
$ echo -n $testvar
Ou você pode fazer isso em uma linha, em vez disso:
$ echo -n $(wc -l < log.txt)
echo -n $(wc -l < log.txt)tem o mesmo efeito.