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.