Как заставить «wc -l» печатать только количество строк без имени файла?


155
wc -l file.txt

выводит количество строк и имя файла.

Мне нужен только сам номер (не имя файла).

я могу это сделать

 wc -l file.txt | awk '{print $1}'

Но может быть, есть лучший способ?


13
wc -l < file.txtвыполняет работу точно и кратко.
Джонатан Леффлер


3
Это вопрос, который я посмотрел дважды. Такое поведение wc неинтуитивно и антипарадигматично для обычной краткости. Эта краткость существует по причине, потому что вы точно не хотите обходить все виды пушистой избыточности. В конце концов, я знаю имя файла, не так ли? То, что я хочу, это количество строк.
Питер - Восстановить Монику

Ответы:


217

Попробуйте так:

wc -l < file.txt

5
В AIX, ksh, перед номером всегда будет пробел. Мы должны использовать | awk '{print $ 1}' или вырезать, чтобы обрезать пробелы. Еще один способ обрезки будет заключен в эхо.
Рао

@rao правильно, это добавит пробел перед числом. Мое решение решает это и проще, чем awk или cut.
Дези Кокрейн

@rao В bash нет места. Откуда берется пространство в ksh? wc -lне должен испускать один, и почему бы ksh ставить перед стандартным выводом программы пробел?
Питер - Восстановить Монику

Несмотря на то, что это правильный обходной путь (и он достаточно прост, что в wc никогда не вносились поправки), он, вероятно, медленнее и не интуитивно понятен. Во-первых, я бы ожидал что-то вроде 4711 [stdin]в качестве вывода.
Питер - Восстановить Монику

Также рассмотрите возможность сопряжения с ним printf "%'d", которое заботится о пространстве и красиво печатает большие числа.
Лев

21
cat file.txt | wc -l

Согласно странице руководства (для версии BSD у меня нет версии GNU для проверки):

Если файлы не указаны, используется стандартный ввод и имя файла не отображается. Подсказка будет принимать ввод до получения EOF или [^ D] в большинстве сред.


3
Я не люблю кошку - конкатенация занимает много времени.
PoGibas

9
wc -l < file.txtимеет тот же эффект.
pjmorse

@user: Проверьте это. Безусловно самая медленная часть будет читать файл с диска.
Сарнольд

11
@ user1286528 затем используйте, wc -l < file.txtчтобы избежать ненужного использования cat. Хотя вы абсолютно безумны, если думаете, что это занимает какое-то заметное время.
Хоббс

12

Чтобы сделать это без пробела, почему бы не:

wc -l < file.txt | bc

Я получаю синтаксические ошибки с этим (Ubuntu 14.04). Я думаю, что есть проблема с именем файла.
MERose

На RHEL 6.7 это вызывает ошибки: $ wc -l file.csv | bc (standard_in) 1: синтаксическая ошибка (standard_in) 1: недопустимый символ: N (standard_in) 1: синтаксическая ошибка (standard_in) 1: синтаксическая ошибка
Родриго Хьорт

3
Я также получаю сообщение об ошибке разбора, но вы можете объединить это с другим ответом, wc -l < file.txtчтобы исправить ошибку разбора и удалить пробел:wc -l < file.txt | bc
jangosteve

11

Как насчет

wc -l file.txt | cut -d' ' -f1

т.е. передать вывод wcв cut(где разделители являются пробелами и выбрать только первое поле)


4
это не лучше, чем wc -l file.txt | awk '{print $1}'пытался ОП.
DoubleDown

1
Быстрее, чем wc -l < file.txtметод. Но необходимо использовать | cut -d' ' -f2в BSD, пока wcкоманда возвращает начальный пробел, например: «34068289 file.txt» вместо «34068289 file.txt».
Сопалахо де Арриерес

@doubleDown, использование awk похоже на использование станка с ЧПУ для резки доски вместо пилы. Используйте пилу для распиливания.
Питер - Восстановить Монику

5

Сравнение методов

У меня была похожая проблема, когда я пытался получить количество символов без начального пробела wc, что привело меня к этой странице. После опробования ответов ниже приведены результаты моего личного тестирования на Mac (BSD Bash). Опять же, это для подсчета символов; для подсчета строк вы бы сделали wc -l. echo -nпропускает разрыв задней линии.

FOO="bar"
echo -n "$FOO" | wc -c                          # "       3"    (x)
echo -n "$FOO" | wc -c | bc                     # "3"           (√)
echo -n "$FOO" | wc -c | tr -d ' '              # "3"           (√)
echo -n "$FOO" | wc -c | awk '{print $1}'       # "3"           (√)
echo -n "$FOO" | wc -c | cut -d ' ' -f1         # "" for -f < 8 (x)
echo -n "$FOO" | wc -c | cut -d ' ' -f8         # "3"           (√)
echo -n "$FOO" | wc -c | perl -pe 's/^\s+//'    # "3"           (√)
echo -n "$FOO" | wc -c | grep -ch '^'           # "1"           (x)
echo $( printf '%s' "$FOO" | wc -c )            # "3"           (√)

Я бы не стал полагаться на cut -f*метод в целом, так как он требует, чтобы вы знали точное число начальных пробелов, которое может иметь любой заданный вывод. И тот, grepкоторый работает для подсчета строк, но не символов.

bcявляется наиболее кратким awkи, perlкажется, немного излишним, но все они должны быть относительно быстрыми и достаточно портативными.

Также обратите внимание, что некоторые из них могут быть адаптированы для обрезки окружающих пробелов из общих строк, а также ( echo `echo $FOO`еще один аккуратный трюк).


1
echo $(printf '%s' "$FOO" | wc -c)это один из тех редких случаев, когда echoкоманда заменяется бесполезно.
tripleee

@tripleee Вау ... на основе вашего кода echo `echo $FOO`;также действует как команда String.trim () для переменной! Это удивительно удобно. Я также добавлю вашу строку в мой ответ.
Beejor



4

Как насчет

grep -ch "^" file.txt

3
Ницца. Очень оригинальное / творческое использование, grepно, проверяя это, оказывается (неудивительно), что это в 2-6 раз медленнее, чем простой / простой wcметод в моих тестах.
17

3

Очевидно, есть много решений для этого. Вот еще один, хотя:

wc -l somefile | tr -d "[:alpha:][:blank:][:punct:]"

Выводит только количество строк, но присутствует символ новой строки ( \n), если вы этого не хотите, замените [:blank:]на [:space:].


Это имеет проблему, когда имя файла содержит номер. Например, для файла test9с 1 строкой вывод будет 19.
Рафаэль Аренс

1

Лучше всего было бы сначала найти все файлы в каталоге, а затем использовать AWK NR (переменная количества записей)

ниже команда:

find <directory path>  -type f | awk  'END{print NR}'

пример : - find /tmp/ -type f | awk 'END{print NR}'


0

Это работает для меня, используя обычный wc -lи sedлишить любой символ, который не является числом.

wc -l big_file.log | sed -E "s/([a-z\-\_\.]|[[:space:]]*)//g"

# 9249133
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.