pegue apenas o inteiro do wc no bash

115

Existe uma maneira de obter o inteiro que wc retorna em bash?

Basicamente, quero escrever os números das linhas e as contagens de palavras na tela após o nome do arquivo.

output: filename linecount wordcount Aqui está o que tenho até agora:

files=`ls`
for f in $files;
do
        if [ ! -d $f ] #only print out information about files !directories
        then
                # some way of getting the wc integers into shell variables and then printing them
                echo "$f $lines $ words"
        fi
done

Jordânia
fonte

Respostas:

57

Você pode usar o cutcomando para obter apenas a primeira palavra da wcsaída de (que é a linha ou contagem de palavras):

lines=`wc -l $f | cut -f1 -d' '`
words=`wc -w $f | cut -f1 -d' '`
Casablanca
fonte
5
Executar wc duas vezes para o mesmo arquivo é ineficiente.
gawi
3
Verdade, é por isso que acho a resposta de James Broadhead muito melhor. Não consegui cuttrabalhar na saída completa de wc $fporque o número de espaços entre os campos varia.
casablanca
1
@casablanca Você pode apertar o número de espaços usando 'tr -s'. Listei mais soluções portáteis para essa pergunta em minha resposta abaixo.
rublo de
Como nesta resposta estamos atribuindo a uma variável, poderíamos eliminar os espaços com
cycollins
88

A resposta mais simples de todas:

wc < filename 
BananaNeil
fonte
5
Mas não produz a saída desejada.
Dave Newton
claro que sim, basta passar os parâmetros apropriados que você faria de qualquer maneira. por exemplo, se você fizer wc -c < file nameisso, ele fornecerá apenas o número inteiro de bytes e nada mais.
BananaNeil
13
Meu ponto é que se você vai responder a uma pergunta de (1,5 ano)) pode muito bem colocar todas as informações na resposta, isso é tudo :)
Dave Newton
opa, apenas releia a pergunta .. #fail, eu estava pesquisando como obter apenas os inteiros, e estava usando informações de uma das respostas, quando descobri uma resposta melhor, e então decidi postar sobre isso. desculpe ..
BananaNeil
3
Você respondeu ao Google, isso é o que conta. :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
82

Somente:

wc -l < file_name

fará o trabalho. Mas esta saída inclui espaços em branco prefixados à medida que wcalinha o número à direita.

Sten
fonte
3
Para obter apenas a contagem de linhas sem espaços em branco: wc -l < foo.txt | xargsref - stackoverflow.com/a/12973694/149428
Taylor Edmiston
1
Assim, enquanto o comando produz uma resposta com espaços iniciais, o questionador estava atribuindo a uma variável e isso elimina os espaços iniciais automaticamente (pelo menos essa foi minha experiência no bash OSX mais antigo). Em outras palavras, lines=`wc -l < $f`resulta em uma "linha" variável cujo valor não tem espaços à esquerda.
Cycollins
E se eu estiver usando find? Recebo um erro: find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -lfunciona bem, mas imprime todos os arquivos. Se eu usar find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -l <, recebo um erro. parse error near '\n'
Nuno Gonçalves
55
wc $file | awk {'print "$4" "$2" "$1"'}

Ajuste conforme necessário para o seu layout.

Também é melhor usar lógica positiva ("é um arquivo") em vez de negativa ("não é um diretório")

[ -f $file ] && wc $file | awk {'print "$4" "$2" "$1"'}
James Broadhead
fonte
1
No meu Windows no Cmder (bash 4.4.12) isso funciona: wc $file | awk '{print $4" "$2" "$1}'- apóstrofos fora de {}.
Grzegorz Gierlik
36

Às vezes, wc produz em formatos diferentes em plataformas diferentes. Por exemplo:

No OS X:

$ echo aa | wc -l

         1

Em Centos:

$ echo aa | wc -l

1

Portanto, usar apenas cortar pode não recuperar o número. Em vez disso, tente tr para excluir caracteres de espaço:

$ echo aa | wc -l | tr -d ' '
Tahsin Turkoz
fonte
23

As respostas aceitas / populares não funcionam no OSX.

Qualquer um dos itens a seguir deve ser portável em bsd e linux.

wc -l < "$f" | tr -d ' '

OU

wc -l "$f" | tr -s ' ' | cut -d ' ' -f 2

OU

wc -l "$f" | awk '{print $1}'
rublo
fonte
11

Se você redirecionar o nome do arquivo para wcele, ele omite o nome do arquivo na saída.

Bash:

read lines words characters <<< $(wc < filename)

ou

read lines words characters <<EOF
$(wc < filename)
EOF

Em vez de usar forpara iterar sobre a saída de ls, faça o seguinte:

for f in *

que funcionará se houver nomes de arquivos que incluam espaços.

Se você não pode usar globbing, você deve canalizar em um while readloop:

find ... | while read -r f

ou usar substituição de processo

while read -r f
do
    something
done < <(find ...)
Pausado até novo aviso.
fonte
Eu votei a favor de você mesmo assim, mas você não precisa redirecionar o nome do arquivo. Basta capturá-lo como um campo adicional. read lines words characters filename <<< $(wc "$f")Ah, e se você costumava * ser protegido contra espaços, também deve colocar aspas duplas na var ao usá-la.
Bruno Bronosky
Usar uma variável adicional é de fato outra maneira de fazer isso, mas se você não for usar a variável (talvez você já tenha o nome do arquivo em uma variável - $fneste caso), é desnecessário. Além disso, o OP perguntou como obter apenas o número inteiro. Você está correto sobre citar uma variável, mas não mostrei o uso da variável, então omiti a menção desse ponto. O for f in *formulário quase sempre deve ser usado em vez de usar a saída de ls, como você sabe.
Pausado até novo aviso.
Eu concordo totalmente neste lsponto. Isso vai te render um prêmio. partmaps.org/era/unix/award.html#ls
Bruno Bronosky
Se você não quiser o nome do arquivo, pode fazer isto:read lines words characters _ <<< $(wc "$f")
@EvanTeitelman: Como discutido em alguns dos comentários acima do seu. $_é apenas uma variável diferente.
Pausado até novo aviso.
3

Se o arquivo for pequeno, você pode chamar wcduas vezes e usar algo como o seguinte, o que evita canos para um processo extra:

lines=$((`wc -l "$f"`))
words=$((`wc -w "$f"`))

A $((...))é a expansão aritmética do bash. Ele remove qualquer espaço em branco da saída de wcneste caso.

Esta solução faz mais sentido se você precisa tanto o LineCount ou o wordcount.

Walter Tross
fonte
2

Que tal com sed?

wc -l /path/to/file.ext | sed 's/ *\([0-9]* \).*/\1/'
mgold
fonte
1
typeset -i a=$(wc -l fileName.dat  | xargs echo | cut -d' ' -f1)
GeorgesMakarios
fonte
1

Tente isto para o resultado numérico:
nlines = $ (wc -l <$ myfile)

Paulonki
fonte
0

Experimente isto:

wc `ls` | awk '{ LINE += $1; WC += $2 } END { print "lines: " LINE  " words: " WC }'

Ele cria uma contagem de linha e uma contagem de palavras (LINE e WC) e aumenta-os com os valores extraídos de wc (usando $ 1 para o valor da primeira coluna e $ 2 para a segunda) e finalmente imprime os resultados.

Aif
fonte
0

"Basicamente, eu quero escrever os números das linhas e contagens de palavras na tela após o nome do arquivo."

answer=(`wc $f`)
echo -e"${answer[3]}
lines:  ${answer[0]}
words:  ${answer[1]}
bytes:  ${answer[2]}"

Saídas: linhas myfile.txt: 10 palavras: 20 bytes: 120

user8155253
fonte
0
files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"
Pedro Reis
fonte
Se você estiver usando de perlqualquer maneira, pode muito bem fazer a contagem de palavras em Perl também. Uma abordagem mais econômica seria canalizar paratr -d '[:space:]'
tripleee