Команда оболочки Linux для фильтрации текстового файла по длине строки
У меня есть 30-гигабайтный образ диска с разделенным на части разделом (думаю dd if=/dev/sda1 of=diskimage
), что мне нужно восстановить некоторые текстовые файлы из. Инструменты вырезания данных, такие как foremost
работать только с файлами с четко определенными заголовками, т.е. не с простыми текстовыми файлами, поэтому я остановился на моем хорошем друге strings
,
strings diskimage > diskstrings.txt
создал 3-гигабайтный текстовый файл, содержащий кучу строк, в основном бесполезных, смешанных с текстом, который я на самом деле хочу.
Большая часть хутора имеет тенденцию быть действительно длинными, непрерывными рядами тарабарщины. Вещи, которые меня интересуют, гарантированно будут меньше 16 КБ, поэтому я собираюсь отфильтровать файл по длине строки. Вот скрипт Python, который я использую для этого:
infile = open ("infile.txt" ,"r");
outfile = open ("outfile.txt","w");
for line in infile:
if len(line) < 16384:
outfile.write(line)
infile.close()
outfile.close()
Это работает, но для дальнейшего использования: есть ли магические заклинания в одну линию? awk
, sed
) что бы фильтровать файл по длине строки?
4 ответа
awk '{ if (length($0) < 16384) print }' yourfile >your_output_file.txt
будет печатать строки короче 16 килобайт, как в вашем собственном примере.
Или, если вам нравится Perl:
perl -nle 'if (length($_) < 16384) { print }' yourfile >your_output_file.txt
Это похоже на ответ Ансгара, но немного быстрее в моих тестах:
awk 'length($0) < 16384' infile >outfile
Это та же скорость, что и другие ответы awk. Опирается на неявное print
истинного выражения, но не нужно тратить время, чтобы разделить линию, как это делает Ансгар.
Обратите внимание, что AWK дает вам if
бесплатно. Команда выше эквивалентна:
awk 'length($0) < 16384 {print}' infile >outfile
Там нет явного if
(или окружающий его набор фигурных скобок), как в некоторых других ответах.
Вот способ сделать это в sed
:
sed '/.\{16384\}/d' infile >outfile
или же:
sed -r '/.{16384}/d' infile >outfile
которые удаляют любую строку, содержащую 16384 (или более) символов.
Для полноты, вот как бы вы использовали sed
чтобы сохранить строки длиннее вашего порога:
sed '/^.\{0,16383\}$/d' infile >outfile
Не очень отличается от уже полученных ответов, но все же короче:
awk -F '' 'NF < 16384' infile >outfile
Вы можете awk
такие как:
$ awk '{ if (length($0) < 16384) { print } }' /path/to/text/file
Это напечатает строки длиннее 16K символов (16 * 1024).
Ты можешь использовать grep
также:
$ grep ".\{,16384\}" /path/to/text/file
Это напечатает строки не более 16K символов.