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

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' '`

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 

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.


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"'}

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 ' '

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}'

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 ...)

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.


2

A co powiesz na to sed?

wc -l /path/to/file.ext | sed 's/ *\([0-9]* \).*/\1/'



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.


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


0
files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.