Вы можете использовать csplit
для разделения на отдельные файлы.
sudo ssldump -i enp0s8 -a -A -H -n -x | csplit - '/^New TCP connection/'
Это разделит ввод на 100 файлов с именами от xx00
до xx99
.
Вы можете установить префикс (по умолчаниюxx
)на что-то другое, используя опцию --prefix=somethingelse
.
Количество цифр, используемых для подсчета файлов (по умолчанию 2 ), можно установить с помощью --digits=X
.
Вам может понадобиться использовать опцию --keep-files
, если csplit
удаляет сгенерированные файлы, когда вы останавливаете процесс (это может интерпретировать прерывание как сбой ).
Вы можете использовать find
для создания списка файлов и передачи его дальше. Это позволяет избежать попытки оболочки раскрыть все пять миллионов имен файлов одной командой
LC_ALL=C find -type f -exec wc -l {} + |
awk '
$2 != "total" {
if (max=="" || $1>max) {max=$1; mxf=$2};
if (min=="" || $1<min) {min=$1; mnf=$2};
}
END { printf "Min %d for %s, max %d for %s\n", min, mnf, max, mxf }
'
find
генерирует список из count имя файла , который передается сценарию awk
. Это, в свою очередь, делает тяжелую работу, ища -и сообщая о -максимальное и минимальное значение и имя файла.
Этот упрощенный код не обрабатывает имена файлов, содержащие пробелы или непечатаемые -символы.
xargs
предназначен именно для этой ситуации и будет работать до тех пор, пока имена файлов не содержат пробелов или новых строк:
find /some/data/dir/with/text/files/ -type f -print | xargs wc -l
Затем вы можете сортировать по количеству строк. Если вас не волнует, какие конкретные файлы содержат минимальные и максимальные строки, вы можете затем извлечь поле количества строк из каждой строки вывода, передать его в uniq
, а затем первая строка результирующего выходного файла будет минимальное количество строк, а последняя строка — максимальное количество строк.
Это, по общему признанию, включает в себя удержание большого количества данных в процессе вычисления информации, которую вы ищете, поэтому, возможно, лучше направить вывод конвейера find | xargs
в скрипт awk
. который просто проходит через каждую строку, а затем отслеживает, меньше ли количество каждой строки, чем минимум, который он видел до сих пор, или больше, чем максимум, который он видел до сих пор.
С последними версиями утилит GNU:
(
printf '/dev/null\0' # for the case where's there's only one file
find. -type f -print0
) |
wc --files0-from=- -l |
sed '1d;$d' | # remove /dev/null and total
sort -n |
sed '1b;$b;d'
Здесь мы передаем список файлов из find
в wc
по конвейеру в wc
stdin, а не через аргументы, поэтому у этого есть несколько преимуществ :нет ограничений на количество аргументы, так как мы не используем системный вызов execve()
. wc
может начать чтение файлов, как только find
их найдет. По сравнению с решениями xargs
или -exec {} +
выполняется только один вызов wc
, поэтому мы получаем максимум одну строку total
.
Обратите внимание, что GNU wc
8.30, по крайней мере, искажает имена файлов, которые содержат символы новой строки. Например, файл с именем ./a<newline>b
отображается здесь как'./a'$'\n''b'
(с использованием стиля ksh93 -$'...'
с кавычками для выражения символа новой строки как$'\n'
). В этом случае вы можете сказать, когда wc
делает это искажение, поскольку все пути к файлам должны начинаться с .
. Поэтому, когда вы видите '
, это означает, что было выполнено искажение.
Вы можете отменить это в оболочке zsh
с флагом расширения параметра Q
:
$ wc -l './a
b'
146 './a'$'\n''b'
$ !! | read -r length file
$ printf '<%s>\n' $file ${(Q)file}
<'./a'$'\n''b'>
<./a
b>
В общем случае вы не можете сказать, когда wc
делает это искажение, хотя, например, оно будет отображать имя файла a<newline>b
или 'a'$'\n''b'
одинаково:
$ wc -l 'a
b' "'a'$'\n''b'"
146 'a'$'\n''b'
1 'a'$'\n''b'
147 total