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.