Как удалить строку, если она длиннее XY?


21

Как я могу удалить строку, если она длиннее, например, 2048 символов?


Вы настаиваете на использовании sed? Это легко, например, в Python. И без сомнения, даже легче в Perl. Хотя вопрос не очень хорошо определен. Скопируйте файл, удалив все строки длиннее 2048 или что-то еще?
Фахим Митха

Ответы:


22
sed '/^.\{2048\}./d' input.txt > output.txt

3
Я получаю сообщение об ошибке sed: 1: "/^.\{2048\}..*/d": RE error: invalid repetition count(s)(Mac OS X)
wedi

1
@wedi вы, вероятно, хотите установить версию GNU вместо версии BSD, которая поставляется с Mac. Это легко с варкой
Freedom_Ben

Вопрос гласит: «Если дольше, чем XY (например, 2048 символов)». Тогда это должно быть> 2048, а не => 2048
ajcg

1
@ajcg,> 2048. Обратите внимание, что в конце регулярного выражения есть дополнительный период, соответствующий 2049-му символу.
Forcefsck

@forcefsck, и было бы лучше, если бы ты убрал это "^"? (с помощью вашей команды вы удаляете только строки, которые «начинаются с XYZ», но если XYZ находится в другой части строки, он не удаляет его)
ajcg

7

Вот решение, которое удаляет строки, содержащие 2049 или более символов:

sed -E '/.{2049}/d' <file.in >file.out

Выражение /.{2049}/dбудет соответствовать любой строке, которая содержит не менее 2049 символов, и удаляет их из входных данных, создавая только более короткую строку в выходных данных.

С awk, печать строк длиной 2048 или короче:

awk 'length <= 2048' <file.in >file.out

Подражая sedрешению буквально с awk:

awk 'length >= 2049 { next } { print }' <file.in >file.out

1
Я получаю сообщение об ошибке sed: 1: "/^.\{400,\}$/d": RE error: invalid repetition count(s)(Mac OS X)
wedi

1
@wedi Теперь обновлен и протестирован на MacOS Mojave.
Кусалананда

2

Нечто подобное должно работать в Python.

of = open("orig")
nf = open("new",'w')
for line in of:         
    if len(line) < 2048:
        nf.write(line)
of.close()
nf.close()

1
Лично, @Faheem, я предпочитаю твой ответ. Причина в том, что мне было очень легко превратить его в «удалить все строки меньше x». Я не использую Python все время, но когда я это делаю, я всегда чувствую, что должен хорошо его изучить.
ixtmixilix

@ixtmixilix: Да, использование полнофункционального языка, такого как Python, довольно гибко. Спасибо за комментарий.
Фахим Митха

2
perl -lne "length < 2048 && print" infile > outfile

+1 Но -lне нужно.
Джозеф Р.

Не работает для меня Perl v5.16.2. Warning: Use of "length" without parentheses is ambiguous at -e line 1. Unterminated <> operator at -e line 1.
WEDI

Вы можете попробовать length($_) > 2048 && print. lengthв length($_)любом случае это ярлык .
МаратC

0

Приведенные выше ответы не работают для меня в Mac OS X 10.9.5.

Следующий код работает:

sed '/.\{2048\}/d',

Хотя и не просили, но предоставили для справки, обратное может быть достигнуто следующим кодом:

sed '/.\{2048\}/!d',


LOL, но sed: 1: "/.\{2048\}/d": RE error: invalid repetition count(s)( Mac OS X, 10.10.4)
Алекс

Ах. Я установил версию GNU вместо версии BSD, которая поставляется с Mac, как предложено выше @Freedom_Ben. Но Кусалананда нашел возможность включить расширенное регулярное выражение. Так что вы должны пойти с его решением, если у вас все еще есть эта проблема. ;)
Веди

0

С gnu-sed вы можете использовать флаг -r, чтобы не вводить обратную косую черту, и запятую, чтобы определить открытый интервал:

sed -r  "/.{2049,}/d" input.txt > output.txt

с:

  • х {2049} означает ровно 2049 хс
  • х {2049,3072} значение от 2049 до 3072 хс
  • х {2049,} означает не менее 2049 хс
  • х {, 2049} значение не более 2049 хс

Для интервалов, чтобы не соответствовать большим шаблонам, вам понадобятся линейные якоря, такие как

sed -r  "/^.{32,64}$/d" input.txt > output.txt 
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.