Заменить указанный c символ в начале и конце любого слова на bash - PullRequest
0 голосов
/ 24 января 2020

Мне нужно удалить символ дефиса «-» только тогда, когда он соответствует шаблону «пробел- [AZ]» или «[AZ] -space». (Предполагая, что все буквы в верхнем регистре, а пробел может быть пробелом или новой строкой)

sample.txt

I AM EMPTY-HANDED AND I- WA-
-ANT SOME COO- COOKIES

Я хочу, чтобы вывод был

I AM EMPTY-HANDED AND I WA
ANT SOME COO COOKIES

Я искал ответы с использованием sed и awk и perl, но я мог только найти ответы, относящиеся к удалению всех символов между двумя шаблонами или заданными c строками, но не указан c символ между [AZ] и пробелом.

Спасибо, куча !!

Ответы [ 5 ]

3 голосов
/ 24 января 2020

Если perl - ваш вариант, попробуйте следующее:

perl -pe 's/(^|(?<=\s))-(?=[A-Z])//g; s/(?<=[A-Z])-((?=\s)|$)//g' sample.txt
  • (?<=\s) - это утверждение с нулевой шириной утверждение взгляда , которое соответствует начальному пробелу без включение его в сопоставляемую подстроку.
  • (?=[A-Z]) - это утверждение нулевой ширины *1013*, которое соответствует конечному символу между A и Z без включения его в сопоставленную подстроку.
  • В результате из исходного текста удаляются только символы da sh, соответствующие приведенному выше шаблону.
  • Второй оператор s/..//g является перевернутой версией первого.
2 голосов
/ 24 января 2020

Если вы можете предоставить Расширенные регулярные выражения до sed (обычно с опцией -E или -r), то вы можете сократить выражение sed до:

sed -E 's/(^|\s)-(\w)/\1\2/g;s/(\w)-(\s|$)/\1\2/g' file

Где базовая форма c - sed -E 's/find1/replace1/g;s/find2/replace2/g' file, которая также может быть записана в виде отдельных выражений sed -E -e 's/find1/replace1/g' -e 's/find2/replace2/g' (на ваш выбор).

Подробности s/find1/replace1/g:

  • find1 is
    • (^|\s) найти и захватить в начале или пробеле,
    • , за которым следует '-' дефис,
    • и затем захватить следующий \w (слово-символ); и
  • replace1 просто \1\2 повторно вставьте оба захвата с первыми двумя обратными ссылками.

Следующее выражение подстановки аналогично, за исключением того, что вы сейчас ищем дефис с последующим пробелом или в конце. Итак, у вас есть:

  • find2, являющийся
    • захватом \w (слово-символ),
    • с последующим дефисом,
    • с последующим захватом либо следующего пробела, либо конца (\s|$), затем
  • replace2 такой же, как и раньше, просто вставьте захваченные символы с помощью обратных ссылок.

В каждом случае g обозначает глобальную замену всех вхождений.

( примечание: слово \w также включает в себя '_' (подчеркивание), поэтому маловероятно, что у вас будет дефис и подчеркивание вместе, но если вы это сделаете, вам нужно использовать список [A-Za-z] вместо \w)

Пример Use / Output

В вашем случае вывод:

$ sed -E 's/(^|\s)-(\w)/\1\2/g;s/(\w)-(\s|$)/\1\2/g' file
I AM EMPTY-HANDED AND I WA
ANT SOME COO COOKIES
2 голосов
/ 24 января 2020

Не могли бы вы попробовать следующее.

awk '{for(i=1;i<=NF;i++){if($i ~ /^-[a-zA-Z]+$|^[a-zA-Z]+-$/){sub(/-/,"",$i)}}} 1' Input_file

Добавление формы решения, отличного от одного вкладыша:

awk '
{
  for(i=1;i<=NF;i++){
    if($i ~ /^-[a-zA-Z]+$|^[a-zA-Z]+-$/){
      sub(/-/,"",$i)
    }
  }
}
1
'  Input_file

Вывод будет следующим.

I AM EMPTY-HANDED AND I WA
ANT SOME COO COOKIES
1 голос
/ 24 января 2020

удаляйте символ дефиса «-» только в том случае, если он соответствует шаблону «пробел- [AZ]» или «[AZ] -space». Предполагая, что все буквы в верхнем регистре, а пробел может быть пробелом или символом новой строки

Это:

sed 's/\( \|^\)-\([A-Z]\)/\1\2/g; s/\([A-Z]\)-\( \|$\)/\1\2/g'
  • s - заменить
    • /
    • \( \|^\) - пробел или начало строки
    • - - дефис ...
    • \(A-Z]\) - один символ верхнего регистра
    • /
    • \1\2 - \1 заменяется первой \(...\) вещью. Таким образом, это заменено пробелом или ничем. \2 заменяется найденным единственным символом верхнего регистра. Фактически - удаляется.
    • /
    • g применяет регулярное выражение во всем мире
  • ; - разделяем два s команды
  • s
    • То же, что и выше. $ означает конец строки.
0 голосов
/ 25 января 2020
awk '{sub(/ -/,"");sub(/^-|-$/,"");sub(/- /," ")}1' file
I AM EMPTY-HANDED AND I WA
ANT SOME COO COOKIES
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...