Команда оболочки 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 символов.

Другие вопросы по тегам