Как да премахнете редове от файл, където има по-малко от 5 и повече от 10 знака в скобите в BASH?

Имам файл като този, съдържащ двойки ( и ) на всеки ред:

This is a sentence (1).
This is another sentence (a note).
This is a sentence (2).
This is another sentence (with another, longer note).

Трябва да изтрия всички редове, в които има по-малко от 5 знака между ( и ) и всички редове, в които има повече от 10 знака между ( и ). Резултатът от горната проба ще изглежда така:

This is another sentence (a note).
  • Никога няма повече от един набор от скоби на ред.
  • Наборите от скоби никога не се разделят на редове.
  • Всеки символ, включително интервали, вътре в скобите може да се счита за знак.

Ето какво имам досега:

grep \([\w{5},\w{10}]\) file.txt

awk -F\( -F\) 'length($2)>5' 'length($2)<10' file.txt

Как мога да изтрия всички редове от файла, които имат твърде малко или твърде много знаци в скобите?


person Village    schedule 22.02.2014    source източник
comment
Не разбирам вашия примерен резултат. Не трябва ли редове 1, 3 и 4 да бъдат премахнати от изхода?   -  person Barmar    schedule 22.02.2014


Отговори (5)


Това ще запази всички редове с 5-10 знака между скобите и ще изтрие всички останали редове.

egrep '\(.{5,10}\)' file.txt
person Barmar    schedule 22.02.2014

Можете да опитате това sed,

sed '/(.\{10,\})\|(.\{,5\})/d' file.txt

sed -n '/(.\{5,10\})/p' file.txt

Тест:

sat:~# sed '/(.\{10,\})\|(.\{,5\})/d' file.txt
This is another sentence (a note).
person sat    schedule 22.02.2014

Можете да използвате това

grep -P "\(.{5,10}\)" filename.txt

Ако искате да зададете резултатите на променлива, тогава можете да използвате това.

var=$( grep -P "\(.{5,10}\)" filename.txt )

or

var=` grep -P "\(.{5,10}\)" filename.txt `

Трябва да отбележите, че във втория пример се използват обратни тикчета, а не единични кавички. И ако искате да отпечатате изхода във файл, можете да използвате и двете

grep -P "\(.{5,10}\)" filename.txt > newfile.txt

or

grep -P "\(.{5,10}\)" filename.txt >> newfile.txt

Където вторият пример ще добави към съществуващ файл или ще създаде нов файл, ако е необходимо.

можете също да използвате egrep вместо grep (ако го направите, нямате нужда от опциите -P

Това, което прави това, е да използва търсене с регулярен израз, който смята, че файлът и програмите grep и egrep ще отпечатат всеки ред, съответстващ на предоставения регулярен израз. В този случай регулярният израз е "\(.{5,10}\)" Наклонената черта означава, че следващият знак е литерал, така че когато е последван от ( или ), тогава казвате литерал „(“, а не това, което обикновено представлява в регулярен израз. .' означава всеки знак с изключение на нови редове, {} указват ограничен брой повторения на последния знак (в този случай това ще бъде всеки знак), а числата вътре са min и max, разделени със запетая.

Така че основно казахме, че grep отпечатва всеки ред, който има низ, съдържащ модела на отворена скоба, след това 5 до 10 знака, които не са нов ред, последвани от затваряща скоба.

Можете да получите повече информация за регулярен израз тук http://www.regular-expressions.info/

person Linx    schedule 22.02.2014

Можете да използвате awk. Пет до десет знака между скоби

awk  '/\(.{5,10}\)/'  filename.txt

или пет до десет скоби без дясна скоба след лява скоба

awk  '/\([^)]{5,10}\)/'  filename.txt
person Fritz G. Mehner    schedule 22.02.2014

Не можете да зададете два разделителя на полета по този начин. Промяна на вашето awk решение:

awk -F"[()]" 'length($2)>5 && length($2)<10’ file.txt
person jaypal singh    schedule 22.02.2014