pobierz tylko liczbę całkowitą z wc w bash

115

Czy istnieje sposób na uzyskanie liczby całkowitej zwracanej przez wc w bash?

Zasadniczo chcę zapisać numery wierszy i liczbę słów na ekranie po nazwie pliku.

output: filename linecount wordcount Oto, co mam do tej pory:

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

Jordania
źródło

Odpowiedzi:

57

Możesz użyć cutpolecenia, aby uzyskać tylko pierwsze słowo wcwyniku (czyli liczbę linii lub słów):

lines=`wc -l $f | cut -f1 -d' '`
words=`wc -w $f | cut -f1 -d' '`
Casablanka
źródło
5
Uruchomienie wc dwa razy dla tego samego pliku jest nieefektywne.
gawi
3
To prawda, dlatego uważam, że odpowiedź Jamesa Broadheada jest znacznie lepsza. Nie mogłem cutpracować nad pełnym wyjściem, wc $fponieważ liczba spacji między polami jest różna.
casablanca,
1
@casablanca Możesz zmniejszyć liczbę spacji za pomocą „tr -s”. W mojej odpowiedzi poniżej wymieniłem bardziej przenośne rozwiązania tego pytania.
rubel
Ponieważ w tej odpowiedzi przypisujemy zmienną, możemy zabić spacje za pomocą
cyklinów
88

Najprostsza odpowiedź w historii:

wc < filename 
BananaNeil
źródło
5
Ale nie daje pożądanego wyniku.
Dave Newton
oczywiście, że tak, po prostu przekazujesz odpowiednie parametry, które i tak byś zrobił. na przykład, jeśli to zrobisz wc -c < file name, otrzymasz tylko całkowitą liczbę bajtów i nic więcej.
BananaNeil
13
Chodziło mi o to, że jeśli masz odpowiedzieć na (1,5-letnie) pytanie), równie dobrze możesz umieścić w odpowiedzi wszystkie informacje, to wszystko :)
Dave Newton,
ups, po prostu ponownie przeczytaj pytanie. #fail, szukałem sposobu na uzyskanie samych liczb całkowitych i korzystałem z informacji z jednej z odpowiedzi, kiedy znalazłem lepszą odpowiedź, a następnie zdecydowałem się o tym napisać . przepraszam ..
BananaNeil
3
Odpowiedziałeś Google, to się liczy. :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
82

Właśnie:

wc -l < file_name

wykona robotę. Ale te dane wyjściowe zawierają przedrostki białe spacje, które wcwyrównują liczbę do prawej.

sten
źródło
3
Aby uzyskać tylko liczbę wierszy bez białych znaków: wc -l < foo.txt | xargsref - stackoverflow.com/a/12973694/149428
Taylor Edmiston
1
Tak więc, podczas gdy polecenie daje odpowiedź z wiodącymi spacjami, pytający przypisywał do zmiennej, co automatycznie usuwa wiodące spacje (przynajmniej takie było moje doświadczenie na starszym bashu OSX). Innymi słowy, lines=`wc -l < $f`daje w wyniku zmienną „line”, której wartość nie zawiera spacji wiodących.
cykliny
A co, jeśli używam orurowania z find? Pojawia się błąd: find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -ldziała poprawnie, ale wyświetla każdy plik. Jeśli używam find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -l <, pojawia się błąd. parse error near '\n'
Nuno Gonçalves
55
wc $file | awk {'print "$4" "$2" "$1"'}

Dostosuj w razie potrzeby do swojego układu.

Ładniej jest też używać logiki pozytywnej („jest plikiem”) zamiast wartości ujemnej („nie jest katalogiem”)

[ -f $file ] && wc $file | awk {'print "$4" "$2" "$1"'}
James Broadhead
źródło
1
Na moim Windowsie w Cmder (bash 4.4.12) to działa: wc $file | awk '{print $4" "$2" "$1}'- apostrofy poza {}.
Grzegorz Gierlik
36

Czasami wyjścia wc w różnych formatach na różnych platformach. Na przykład:

W OS X:

$ echo aa | wc -l

         1

W Centos:

$ echo aa | wc -l

1

Więc użycie tylko cięcia może nie odzyskać numeru. Zamiast tego spróbuj tr, aby usunąć znaki spacji:

$ echo aa | wc -l | tr -d ' '
Tahsin Turkoz
źródło
23

Zaakceptowane / popularne odpowiedzi nie działają w systemie OSX.

Każde z poniższych powinno być przenośne w systemach bsd i linux.

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

LUB

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

LUB

wc -l "$f" | awk '{print $1}'
rubel
źródło
11

Jeśli przekierujesz do niego nazwę pliku wc, pomija nazwę pliku na wyjściu.

Grzmotnąć:

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

lub

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

Zamiast używać fordo iteracji po danych wyjściowych ls, wykonaj następujące czynności:

for f in *

co zadziała, jeśli istnieją nazwy plików zawierające spacje.

Jeśli nie możesz użyć globbingu, powinieneś potokować do while readpętli:

find ... | while read -r f

lub użyj zastępowania procesu

while read -r f
do
    something
done < <(find ...)
Wstrzymano do odwołania.
źródło
I tak zagłosowałem za tobą, ale nie musisz przekierowywać nazwy pliku. Po prostu zarejestruj to jako dodatkowe pole. read lines words characters filename <<< $(wc "$f")Aha, i jeśli kiedyś * byłeś zabezpieczony przed spacjami, chcesz również podwójnie zacytować var, kiedy go używasz.
Bruno Bronosky
Użycie dodatkowej zmiennej jest rzeczywiście innym sposobem, ale jeśli nie zamierzasz jej używać (być może masz już nazwę pliku w zmiennej - $fw tym przypadku), jest to niepotrzebne. Ponadto OP zapytał, jak uzyskać tylko liczbę całkowitą. Masz rację, jeśli chodzi o cytowanie zmiennej, ale nie pokazałem użycia zmiennej, więc pominąłem wzmiankę o tym. for f in *Forma powinna być prawie zawsze stosowany zamiast używania wyjścia ls, jak wiesz.
Wstrzymano do odwołania.
Całkowicie się z tym zgadzam ls. To da ci nagrodę. partmaps.org/era/unix/award.html#ls
Bruno Bronosky
Jeśli nie chcesz nazwy pliku, możesz to zrobić:read lines words characters _ <<< $(wc "$f")
@EvanTeitelman: Jak omówiono w kilku komentarzach powyżej Twojego. $_jest po prostu inną zmienną.
Wstrzymano do odwołania.
3

Jeśli plik jest mały, możesz pozwolić sobie na wcdwukrotne wywołanie i użycie czegoś podobnego do poniższego, co pozwala uniknąć przekierowania do dodatkowego procesu:

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

Jest $((...))to arytmetyczne rozszerzenie bash. W wctym przypadku usuwa wszelkie spacje z danych wyjściowych programu .

Takie rozwiązanie sprawia, że więcej sensu, jeśli trzeba albo się linecount lub z WordCount.

Walter Tross
źródło
2

A co powiesz na to sed?

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

Spróbuj tego dla wyniku liczbowego:
nlines = $ (wc -l <$ myfile)

paulonki
źródło
0

Spróbuj tego:

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

Tworzy liczbę wierszy i liczbę słów (LINE i WC), a następnie zwiększa je o wartości wyodrębnione z wc (używając 1 $ za wartość pierwszej kolumny i 2 $ za drugą), a na końcu drukuje wyniki.

Aif
źródło
0

„Zasadniczo chcę zapisać numery wierszy i liczbę słów na ekranie po nazwie pliku”.

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

Wyniki: linie myfile.txt: 10 słów: 20 bajtów: 120

user8155253
źródło
0
files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"
Pedro Reis
źródło
Jeśli perlmimo wszystko używasz , równie dobrze możesz policzyć słowa w Perlu. Bardziej ekonomicznie podejście byłoby rurytr -d '[:space:]'
tripleee