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 printf
geralmente é 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, bash
remove 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:
%s
marcador 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$//'
sed
não adicionará um \0
ao final do fluxo se o delimitador estiver definido como NUL
via -z
, enquanto que para criar um arquivo de texto POSIX (definido para terminar em a \n
), ele sempre produzirá um final \n
sem -z
.
Por exemplo:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender
E para provar que não foi NUL
adicionado:
$ { 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+$//'
sed
não fornece -z
.
Se você quiser imprimir qualquer coisa no Bash sem fim de linha, faça o eco com a -n
chave.
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.