Mam następujące trzy konstrukcje w skrypcie bash:
NUMOFLINES=$(wc -l $JAVA_TAGS_FILE)
echo $NUMOFLINES" lines"
echo $(wc -l $JAVA_TAGS_FILE)" lines"
echo "$(wc -l $JAVA_TAGS_FILE) lines"
Oba generują identyczne dane wyjściowe po uruchomieniu skryptu:
121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines
Oznacza to, że wyświetlana jest również nazwa pliku (czego nie chcę). Dlaczego te rysiki zawodzą i jak powinienem wypisać czysty:
121711 lines
?
Odpowiedzi:
Przykład z wykorzystaniem własnych danych
Możesz uniknąć osadzania nazwy pliku w zmiennej NUMOFLINES , używając przekierowania z JAVA_TAGS_FILE zamiast przekazywania nazwy pliku jako argumentu do wc . Na przykład:
NUMOFLINES=$(wc -l < "$JAVA_TAGS_FILE")
Objaśnienie: Użyj potoków lub przekierowania, aby uniknąć nazw plików w wyjściu
Narzędzie wc nie wypisze nazwy pliku w swoim wyjściu, jeśli dane wejściowe są pobierane z potoku lub operatora przekierowania. Rozważ te różne przykłady:
# wc shows filename when the file is an argument $ wc -l /etc/passwd 41 /etc/passwd # filename is ignored when piped in on standard input $ cat /etc/passwd | wc -l 41 # unusual redirection, but wc still ignores the filename $ < /etc/passwd wc -l 41 # typical redirection, taking standard input from a file $ wc -l < /etc/passwd 41
Jak widać, jedyną sytuacją , w której wc wypisze nazwę pliku, jest przekazanie jej jako argumentu, a nie danych na standardowym wejściu. W niektórych przypadkach możesz chcieć wydrukować nazwę pliku, więc warto wiedzieć, kiedy zostanie wyświetlona.
źródło
wc
nie można uzyskać nazwy pliku, jeśli jej nie podasz.wc -l < "$JAVA_TAGS_FILE"
źródło
wc
stdin, jak pokazano w odpowiedzi. Więccat "$JAVA_TAGS_FILE" | wc -l
albo, równoważniewc -l < "$JAVA_TAGS_FILE"
. W ten sposóbwc
pobiera tylko surowe dane, a nie nazwę pliku.Możesz także użyć awk:
awk 'END {print NR,"lines"}' filename
Lub
awk 'END {print NR}' filename
źródło
(zastosuj na Macu i prawdopodobnie innych Uniksach)
W rzeczywistości istnieje problem z podejściem wc: nie liczy ostatniej linii, jeśli nie kończy się symbolem końca linii.
Użyj tego zamiast tego
lub nawet lepiej (dzięki gniourf_gniourf):
nblines=$(grep -c '' file.txt)
Uwaga: działa również podejście chilicuil w awk.
źródło
nblines=$(grep -c '' file)
zamiast tego (co jest kanonicznym sposobem liczenia niekompletnych wierszy w tym przypadku). Zauważ jednak, że zgodnie z POSIX liczysz niekompletne wiersze (a nie wiersze ). W rzeczywistości masz do czynienia z plikiem binarnym, a nie plikiem tekstowym .nblines=$(($(cat "file.txt" | wc -l) + 1))
To bardzo proste:
NUMOFLINES=$(cat $JAVA_TAGS_FILE | wc -l )
lub
NUMOFLINES=$(wc -l $JAVA_TAGS_FILE | awk '{print $1}')
źródło
cat
, będziesz miał drugi przykład wtedy, ponieważwc -l
zwraca 2 kolumny, gdy jest używany tylko z plikiem.Zwykle używam funkcji „back tick” w bash
export NUM_LINES=`wc -l filename`
Zauważ, że „tick” to „back tick”, np. „Nie jest zwykłym pojedynczym cudzysłowem
źródło