Como fazer com que “wc -l” imprima apenas o número de linhas sem o nome do arquivo?

155
wc -l file.txt

gera o número de linhas e o nome do arquivo.

Eu preciso apenas do número em si (não do nome do arquivo).

eu posso fazer isso

 wc -l file.txt | awk '{print $1}'

Mas talvez haja uma maneira melhor?

PoGibas
fonte
13
wc -l < file.txtfaz o trabalho de forma precisa e concisa.
Jonathan Leffler
2
Possível duplicado de obter apenas o número inteiro de wc em bash
Ciro Santilli郝海东冠状病六四事件法轮功
3
Esta é uma pergunta que pesquisei duas vezes agora. Esse comportamento do wc não é intuitivo e antiparadigmático para a tênue complexidade usual. Essa dispersão existe por um motivo, porque você exatamente não deseja solucionar todos os tipos de redundância fofa. Afinal, eu sei o nome do arquivo, não é? O que eu quero é a contagem de linhas.
Peter - Restabelece Monica

Respostas:

217

Tente desta maneira:

wc -l < file.txt
Norman Ramsey
fonte
5
No AIX, ksh, isso sempre terá um espaço antes do número. Nós temos que usar | awk '{print $ 1}' ou um corte, para aparar os espaços. Outra maneira de aparar seria anexar um eco.
rao 18/02
@rao está correto, isso adicionará um espaço antes do número. Minha solução resolve isso e é mais simples do que awk ou cut.
Desi Cochrane
@rao Não há espaço com o bash. De onde vem o espaço em ksh? wc -lnão deve emitir um e por que o ksh precederá a saída padrão de um programa com um espaço?
Peter - Restabelece Monica
Embora esta seja a solução correta (e seja fácil o suficiente que nunca tenhamos sido alterados), provavelmente é mais lenta e pouco intuitiva. Por um lado, eu esperaria algo como 4711 [stdin]a saída.
Peter - Restabelece Monica
Considere também emparelhar com printf "%'d", que cuida do espaço e imprime grandes números de maneira agradável.
Leo
21
cat file.txt | wc -l

De acordo com a página do manual (para a versão BSD, não tenho uma versão GNU para verificar):

Se nenhum arquivo for especificado, a entrada padrão será usada e nenhum nome de arquivo será exibido. O prompt aceitará entrada até receber EOF ou [^ D] na maioria dos ambientes.

pjmorse
fonte
3
Eu não gosto de gatos - a concatenação consome muito tempo.
precisa saber é o seguinte
9
wc -l < file.txttem o mesmo efeito.
Pjmorse
@ usuário: Teste. De longe, a parte mais lenta será ler o arquivo do disco.
sarnold
11
@ user1286528 use wc -l < file.txtpara evitar o uso inútil de gato. Embora você seja absolutamente louco, se acha que está consumindo um tempo perceptível.
precisa
12

Para fazer isso sem o espaço à esquerda, por que não:

wc -l < file.txt | bc
Desi Cochrane
fonte
Eu recebo erros de sintaxe com isso (Ubuntu 14.04). Eu acho que há um problema com o nome do arquivo.
MERose 07/07
Em um RHEL 6.7, gera erros: $ wc -l file.csv | bc (standard_in) 1: erro de sintaxe (standard_in) 1: carácter ilegal: N (standard_in) 1: erro de sintaxe (standard_in) 1: erro de sintaxe
Rodrigo Hjort
3
Eu também obter um erro de análise, mas você pode combinar isso com a outra resposta de usar wc -l < file.txtpara corrigir o erro de análise e remover o espaço:wc -l < file.txt | bc
jangosteve
11

E se

wc -l file.txt | cut -d' ' -f1

ou seja, canalize a saída para wcinto cut(onde delimitadores são espaços e escolha apenas o primeiro campo)

Neil Albert
fonte
4
isso não é melhor do que o wc -l file.txt | awk '{print $1}'OP tentou.
doubleDown 6/08/13
1
Mais rápido que o wc -l < file.txtmétodo. Mas deve usar | cut -d' ' -f2no BSD, desde que o wccomando retorne um espaço à esquerda, exemplo: "34068289 file.txt", em vez de "34068289 file.txt".
Sopalajo de Arrierez
@doubleDown bem, usar o awk é como usar uma máquina CNC para cortar uma placa em vez de uma serra. Use uma serra para serrar.
Peter - Restabelece Monica
5

Comparação de Técnicas

Tive um problema semelhante ao tentar obter uma contagem de caracteres sem o espaço em branco fornecido pelo wc, o que me levou a esta página. Depois de tentar as respostas aqui, a seguir estão os resultados dos meus testes pessoais no Mac (BSD Bash). Novamente, isso é para contagem de caracteres; pela contagem de linhas que você faria wc -l. echo -nomite a quebra de linha à direita.

FOO="bar"
echo -n "$FOO" | wc -c                          # "       3"    (x)
echo -n "$FOO" | wc -c | bc                     # "3"           (√)
echo -n "$FOO" | wc -c | tr -d ' '              # "3"           (√)
echo -n "$FOO" | wc -c | awk '{print $1}'       # "3"           (√)
echo -n "$FOO" | wc -c | cut -d ' ' -f1         # "" for -f < 8 (x)
echo -n "$FOO" | wc -c | cut -d ' ' -f8         # "3"           (√)
echo -n "$FOO" | wc -c | perl -pe 's/^\s+//'    # "3"           (√)
echo -n "$FOO" | wc -c | grep -ch '^'           # "1"           (x)
echo $( printf '%s' "$FOO" | wc -c )            # "3"           (√)

Eu não confiaria no cut -f*método em geral, pois exige que você saiba o número exato de espaços à esquerda que qualquer saída pode ter. E o grepque funciona para contar linhas, mas não caracteres.

bcé o mais conciso awke perlparece um pouco exagerado, mas todos devem ser relativamente rápidos e portáteis o suficiente.

Observe também que alguns deles podem ser adaptados para aparar o espaço em branco circundante a partir de seqüências de caracteres gerais (além de echo `echo $FOO`outro truque).

Beejor
fonte
1
echo $(printf '%s' "$FOO" | wc -c)é uma das raras ocasiões em que echocom uma sub - substituição de comando não é inútil.
Tripleee
@tripleee Whoa ... com base no seu código, echo `echo $FOO`;também age como um comando String.trim () em uma variável! Isso é incrivelmente útil. Também adicionarei sua linha à minha resposta.
Beejor 6/11/19
Talvez por contexto ver também Quando a envolver aspas em torno de uma variável shell
tripleee
... bem como Por que é printfmelhor que echo?
Tripleee
4

E se

grep -ch "^" file.txt
MeIsMich
fonte
3
Agradável. Uso muito original / criativo, grepmas verificá-lo (sem surpresa) é 2x a 6x mais lento que o wcmétodo mais simples / direto nos meus testes.
Arielf 21/04/19
3

Obviamente, existem muitas soluções para isso. Aqui está outro:

wc -l somefile | tr -d "[:alpha:][:blank:][:punct:]"

Isso gera apenas o número de linhas, mas o caractere de nova linha à direita ( \n) está presente; se você não quiser, substitua [:blank:]por [:space:].

Bouchaala Reda
fonte
Isso ocorre quando o nome do arquivo tem um número. Por exemplo, para o arquivo test9com 1 linha, a saída será 19.
Raphael Ahrens
1

A melhor maneira seria encontrar todos os arquivos no diretório e depois usar o AWK NR (número de variáveis ​​variáveis)

abaixo está o comando:

find <directory path>  -type f | awk  'END{print NR}'

exemplo: - find /tmp/ -type f | awk 'END{print NR}'

user128364
fonte
0

Isso funciona para mim usando o normal wc -le sedpara remover qualquer caractere que não seja um número.

wc -l big_file.log | sed -E "s/([a-z\-\_\.]|[[:space:]]*)//g"

# 9249133
joseluisq
fonte