bash echo кількість рядків файлу, вказаних у змінній bash без імені файлу


79

У мене є такі три конструкції в сценарії bash:

NUMOFLINES=$(wc -l $JAVA_TAGS_FILE)
echo $NUMOFLINES" lines"

echo $(wc -l $JAVA_TAGS_FILE)" lines"

echo "$(wc -l $JAVA_TAGS_FILE) lines"

І вони обидва видають однакові результати при запуску сценарію:

121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines
121711 /home/slash/.java_base.tag lines

Тобто ім'я файлу також повторюється (що я не хочу). Чому ці сценарії виходять з ладу і як мені вивести чистий:

121711 lines

?


Відповіді:


157

Приклад використання власних даних

Ви можете уникнути вбудовування імені файлу у змінну NUMOFLINES , використовуючи переспрямування з JAVA_TAGS_FILE , а не передаючи ім’я файлу як аргумент wc . Наприклад:

NUMOFLINES=$(wc -l < "$JAVA_TAGS_FILE")

Пояснення: Використовуйте канали або переспрямування, щоб уникнути імен файлів у вихідних даних

Туалет утиліта не друкуватиме ім'я файлу в його виході , якщо вхідні дані беруться від оператора труби або перенаправлення. Розглянемо ці різні приклади:

# 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

Як бачите, єдиний раз, коли wc надрукує ім'я файлу, це коли його передано як аргумент, а не як дані на стандартному введенні. У деяких випадках може знадобитися надрукувати ім’я файлу, тому корисно зрозуміти, коли воно буде відображатися.


1
пам’ятайте, що цей підхід не включатиме останній рядок, якщо останній рядок не закінчується символом кінця рядка. Дивіться моє виправлення нижче.
— лінг

15

wc не може отримати ім'я файлу, якщо ви його не вказали.

wc -l < "$JAVA_TAGS_FILE"

2
Ну, тоді не робіть. Просто передайте файл на wcstdin, як показано у відповіді. Так cat "$JAVA_TAGS_FILE" | wc -lчи, що те ж саме, wc -l < "$JAVA_TAGS_FILE". Таким чином, wcотримуються лише необроблені дані, а не ім’я файлу.
— Вітіко,


5

(застосовувати на Mac та, можливо, інших Unix)

Насправді існує проблема з підходом wc: він не враховує останній рядок, якщо не закінчується символом кінця рядка.

Використовуйте це замість цього

nbLines=$(cat -n file.txt | tail -n 1 | cut -f1 | xargs)

або навіть краще (спасибі gniourf_gniourf):

nblines=$(grep -c '' file.txt)

Примітка: Підхід awk від chilicuil також працює.


2
Дуже заплутаний метод! Можливо, ви захочете nblines=$(grep -c '' file)замість цього (що є канонічним способом підрахунку неповних рядків у цьому випадку). Зверніть увагу, що відповідно до POSIX, ви рахуєте неповні рядки (а не рядки ). Ви насправді маєте справу з двійковим файлом, а не з текстовим файлом .
— gniourf_gniourf

@gniourf_gniourf Дякую, я не знав про це, це чудово працює і є ще більш лаконічним.
— лінг

це може бути кращим рішеннямnblines=$(($(cat "file.txt" | wc -l) + 1))
— Андрій Ізман

3

Це дуже просто:

NUMOFLINES=$(cat $JAVA_TAGS_FILE | wc -l )

або

NUMOFLINES=$(wc -l $JAVA_TAGS_FILE | awk '{print $1}')

Перше - марне використання кота.
— кап

@kap Ні, це виглядає лише так. Якщо ви позбудетеся cat, у вас буде другий приклад, тому що wc -lповертає 2 стовпці, коли він використовується лише з файлом.
— Слава Семушин

-3

Зазвичай я використовую функцію "тикання" bash

export NUM_LINES=`wc -l filename`

Зверніть увагу, що "галочка" - це "зворотна галочка", наприклад "не звичайна одинарна лапка


5
Це просто інші позначення, і це не вирішує проблему імені файлу, яка є частиною результату.
— Іззі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.