Я думаю, вы можете просто использовать awk напрямую:
awk '/331881/ { exit } 1' test.out
Это напечатает все строки, но для строки, соответствующей 331881
, выйдите.
Вам не нужна опция -l
, так как вас не интересуют такие сведения о файле, как права доступа, владелец и размер. Нужно только имя файла.
Команда grep
не работает. grep
все равно не поможет, так как в вопросе предлагается отдельно считать файлы tcp и udp.
Для подсчета файлов вы можете использовать ls|wc -l
. Для подсчета файлов, имена которых начинаются с «tcp»:ls tcp*|wc -l
. Сделайте то же самое для «udp» и объедините два числа в эхе:
echo -e "$(ls /proc/sys/net/ipv4/tcp*|wc -l) tcp\n$(ls /proc/sys/net/ipv4/udp*|wc -l) udp" > out
-e
требуется для обработки новой строки.
Это не сработало бы, если бы имена файлов содержали символы новой строки, но мы можем с уверенностью предположить, что в /proc/sys/net/ipv4 это не так.
Перечитав вопрос, я не уверен, что мой ответ правильный. Он просто считает файлы, а не параметры. Теперь мне нужно сделать предположение :Параметр — это слово в таком файле. Большинство файлов содержат одно слово, но некоторые содержат больше. Для подсчета слов используйте wc -w
. Вместо ls
используйте cat
для доступа к содержимому файла :
echo -e "$(cat /proc/sys/net/ipv4/tcp*|wc -w) tcp\n$(cat /proc/sys/net/ipv4/udp*|wc -w) udp" > out
Все, что вам не хватает в вашем примере, это передать его uniq -c
вот так:
ls -l /proc/sys/net/ipv4 | grep -n "tcp\|udp"| cut -d " " -f 10| cut -c 1-3 | uniq -c
Вот что я получил, когда запустил его в своей системе:
$ ls -l /proc/sys/net/ipv4 | grep -n "tcp\|udp"| cut -d " " -f 10| cut -c 1-3 | uniq -c
68 tcp
5 udp
В этом случае я бы не пытался использовать конвейеры или перенаправление для подсчета файлов, а вместо этого позволил бы оболочке сделать это за меня:
$ set -- /proc/sys/net/ipv4/tcp*
$ printf '%d tcp\n' "$#"
73 tcp
$ set -- /proc/sys/net/ipv4/udp*
$ printf '%d udp\n' "$#"
5 udp
или, записанный в выходной файл:
{ set -- /proc/sys/net/ipv4/tcp*; printf '%d tcp\n' "$#"
set -- /proc/sys/net/ipv4/udp*; printf '%d udp\n' "$#"; } >outputfile
Вы можете искусственно превратить это в единую составную команду, но никто не будет писать такой код:
$ set -- /proc/sys/net/ipv4/tcp* && printf '%d tcp\n' "$#" && set -- /proc/sys/net/ipv4/udp* && printf '%d udp\n' "$#"
73 tcp
5 udp
В обоих этих наборах команд файлы подсчитываются путем расширения шаблона подстановки имен файлов, установки позиционных параметров в расширенный список путей, а затем простого вывода количества элементов в списках.
Вы получите неверный подсчет, если ни один из шаблонов ничему не соответствует (1 вместо 0 ). Вы можете исправить это, установив параметр оболочки nullglob
в bash
.
Это также покрывает теоретические крайние случаи с именами файлов, содержащими символы новой строки и любые другие странные символы.
Команда awk
, которая делает то же самое, что и выше (, т. е. подсчитывает, сколько раз встречаются имена файлов, начинающиеся с tcp
и udp
):
awk '
BEGIN {
for (i=1;i<ARGC;++i) { sub(".*/","",ARGV[i]); sub("_.*","",ARGV[i]); c[ARGV[i]]++ }
for (i in c) print i, c[i]
}' /proc/sys/net/ipv4/{tcp,udp}*
Решение, к которому я пришел, было следующим:
ls /proc/sys/net/ipv4 | grep "tcp\|udp" | cut -d "_" -f1 |sort |uniq -c > output.txt
Спасибо всем за помощь:)