Як видалити рядок, якщо довше XY?


21

Як я можу видалити рядок, якщо він довший, наприклад: 2048 символів?


Ви наполягаєте на використанні sed? Це легко, наприклад, в python. І без сумніву, навіть простіше в perl. Хоча питання не дуже чітко визначене. Скопіювати файл, видаливши всі рядки довше 2048 року чи щось інше?
Faheem Mitha

Відповіді:


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 є досить гнучким. Дякуємо за коментар
Faheem Mitha

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($_)будь-якого.
MaratC

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)
alex grey

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

0

За допомогою gnu-sed ви можете використовувати прапор -r, щоб уникнути введення косої риски та кома для визначення відкритого інтервалу:

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

з:

  • x {2049} що означає рівно 2049 xs
  • x {2049,3072} що означає від 2049 до 3072 хс
  • x {2049,} означає щонайменше 2049 хс
  • x {, 2049}, що означає максимум 2049 xs

Щоб інтервали не відповідали більшій схемі, вам знадобляться якорні лінії

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