Якщо ви кваліфікуєте слово, щоб означати будь-яку послідовність з 1 або більше непорожніх символів, то відповідь, безумовно, так, і це робиться дуже просто. Це відбувається тому , що [[:blank:]]*
і [^[:blank:]]*
є логічні доповнення і - при умови , всі символи в рядку є повними - [[:blank:]]*
U [^[:blank:]]*
можна описати будь-яку можливу рядок в такий же спосіб .*
робить.
Якщо в рядку існує неповний символ або недійсна послідовність байтів, то його не можна успішно описати головою до хвоста - як це іноді може траплятися при інтерпретації рядка в неправильному кодуванні. Щоб забезпечити повноцінний символ на байт у будь-якому рядку, локальність C може бути вимушена як:
LC_ALL=C sed ...
... що дозволить уникнути будь - яких проблем , яка описує рядок від голови до хвоста з всеохоплюючим малюнком , такими як .*
або([ ]*[^ ]*)*
Повністю доповнюючий візерунок може повторюватися стільки разів, скільки потрібно зліва направо, довжина будь-якої струни приземляється на останнє можливе виникнення без будь-якого розриву шаблону. Це, безумовно, регулярна мова.
BRE:
sed 's/\(\([^[:blank:]]*\)[[:blank:]]*\)*/\2/'
ERE:
sed -E 's/(([^[:blank:]]*)[[:blank:]]*)*/\2/'
Обидві ці версії все ще будуть друкувати порожні рядки, і це тому, що *
зірка Клейна відповідає нулю або більше випадків візерунка. Спочатку він відповідає нулю або більше не пустих символів, потім нуль або більше порожніх символів, потім нуль або більше випадків згрупованих збігів, поки він не зрівняється з рядком у повному обсязі.
Зібравши все це, магія відбувається в заміні - посилання повертаються групами \1
і \2
є останніми явищами кожної. Отже, коли здійснюється заміна, весь рядок замінюється лише останнім явищем у рядку нульового або більше не порожніх символів - або підгрупі \2
.
Звичайно, це працює для будь-якого можливого рядка - навіть порожнього - що означає, що обидві форми друкують символи нового рядка для рядків, які містять лише порожні символи або взагалі жодні. Щоб вирішити це, ви можете зробити кілька речей, але спочатку давайте трохи полегшимо набір класів персонажів:
b='[:blank:]'
Тепер, щоб надрукувати лише якщо рядок містить один чи більше непорожніх символів, ви можете:
BRE:
sed -n "s/\(\([^$b]*\)[$b]*\)*/\2/;/./p"
ERE:
sed -En "/[^$b]/s/(([^$b]*)[$b]*)*/\2/p"
- Справа BRE - підміна завжди виконується, і друкуються лише пробіли з малюнком, принаймні одним символом, що залишився.
- Випадок ERE - заміщення проводиться лише коли-небудь на просторі шаблону, що містить принаймні одне не порожнє значення.
Будь-яка форма буде працювати з будь-яким методом - доки синтаксис правильний.
-n
Перемикач відключає автоматичний друку з шаблону, і p
прапор в s///
ubstitution або /
адресних /
команд видає його результати тільки в разі успіху.
Ця ж логіка може бути застосована для отримання будь {num}
- якого явища, а також, як:
BRE:
sed -n "s/\([$b]*\([^$b]\{1,\}\)\)\{num\}.*/\2/p"
ERE:
sed -En "s/([$b]*([^$b]+)){num}.*/\2/p"
... де num
обидва regexps можуть бути замінені цифрою, щоб друкувати лише {num}
вказане виникнення послідовності непорожніх символів. Тут дещо інша форма використовується для того, щоб підрахунок не був перекошений для провідного простору в рядку.
Зверніть увагу , що -E
перемикач ERE до sed
підтримуються як в BSD і GNU версії, хоча це не є ще POSIX стандартного синтаксису.
sed
?