При подсчете строк с помощью wc не печатайте сообщение об ошибке, если каталог

12

Я хочу подсчитать общее количество строк во всех /etcфайлах, но не в файлах в подкаталогах, поэтому я набрал: wc -l /etc/* | tail -1и результат будет такой:

xxxx is a directory 
yyyy is a directory
total 1752

Мой вопрос, как я могу избавиться (удалить) эти комментарии, и есть ли лучший способ сделать этот тип подсчета?

Хамза
источник
1
Я думаю, что использование find не на 100% правильно, потому что в / etc есть не только обычные файлы f, но и ссылки l. так что эта версия намного лучше: $ sudo wc -l / etc / * 2> / dev / null | Хвост -1
Хамза

Ответы:

14

Вы можете вывести сообщения об ошибках в / dev / null

$ wc -l /etc/* 2>/dev/null | tail -1

С помощью этой команды вы видите только количество строк в файлах, которые доступны для чтения всем пользователям. Чтобы увидеть количество строк во всех файлах, вам нужно повысить уровень команды sudo.

$ sudo wc -l /etc/* 2>/dev/null | tail -1
Л.Д. Джеймс
источник
8

Изолировать файлы и запустить на них wc

То, что wc -l /etc/*делает это, *будет распространяться на все элементы внутри /etc/каталога. Таким образом, цель состоит в том, чтобы затем изолировать файлы и выполнить wcна них. Есть несколько способов сделать это.

для цикла с тестом

Команда test, или, более часто, сокращенно as, [может использоваться для определения того, является ли элемент обычным файлом, например так:

[ -f "$FILE" ]

Таким образом, мы можем перебирать все элементы /etc/и запускать wcих, если и только если вышеприведенная команда возвращает true. Вот так:

for i in /etc/*; do [ -f "$i" ] && wc -l "$i" ; done             

находить

Мы также можем использовать findс -maxdepth, -typeи -execфлагами

find /etc/ -maxdepth 1 \( -type f -o -type l \) -exec wc -l {} +

  • -maxdepthинформирует о том, как глубоко в структуре каталогов идти; значение 1 означает только те файлы в каталоге, который мы хотим.
  • -type f говорит ему искать обычные файлы, ИЛИ (представленные -oфлагом) для символических ссылок (представленных type l). Все эти качества заключены в квадратные скобки, ()с \которыми экранируются, так что оболочка интерпретирует их как часть findкоманды, а не как-то еще.
  • -exec COMMAND {} +Структура здесь запускает любую команду, которую мы ей даем, +указывая , что нужно взять все найденные файлы и вставить их в качестве аргументов командной строки в КОМАНДУ.

Чтобы получить общее количество, мы могли бы выводить трубу tailтак

$ find /etc/ -maxdepth 1 \( -type f -o -type l \) -exec wc -l {} + | tail -n 1           
[sudo] password for xieerqi: 
 11196  total

Примечание

Его проще использовать wc -l /etc/* 2>/dev/null | tail -1, как в ответе Л.Дж Джеймса, однако это findдолжно стать частью привычки иметь дело с файлами, чтобы избежать обработки сложных имен файлов. Подробнее об этом читайте в эссе « Как правильно обращаться с именами файлов»

Сергей Колодяжный
источник
5

find делает это легко:

sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*')

Выход:

...
828 /etc/mime.types
25 /etc/ts.conf
66 /etc/inputrc
 0 /etc/subgid-
8169 total

НО, если вы просто хотите, чтобы число выводилось и ничего больше:

sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*') | grep total | awk '{print $1}'

РЕДАКТИРОВАТЬ : newlinesошибка кос сказал, преобладает. Только используя -execэто исправляет. Также /etcне содержит таких файлов.

Выход:

8169

Как указано в kos , приведенная выше команда может быть уменьшена до:

sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*') | awk 'END {print $1}'

РЕДАКТИРОВАТЬ : newlinesошибка кос сказал, преобладает. Только используя -execэто исправляет. Также /etcне содержит таких файлов.

Выход:

8169
Рафаэль
источник
4
Какова цель -iname '*'? не findсоответствует всем по умолчанию?
SteelDriver
@steeldriver - без меня это не сработало '*'.
Рафаэль
2

Использование z-shell ( zsh), королевы оболочек , вместо bash.

sudo wc -l /etc/*(.) | tail -1
AB
источник