특수 문자 사이의 단어 제거

특수 문자 사이의 단어 제거

sed를 사용하여 두 특수 문자 사이의 모든 단어를 제거하는 방법은 무엇입니까? 원래 행도 결과에 포함되어야 합니다.

현재 코드:

echo 'a "removeme" b +removeme+ c *removeme#d+removeme~ .123' | sed -r '/\W/ p; s/\W[^\W]*\W//g'

결과:

a "removeme" b +removeme+ c *removeme#d+removeme~ .123
a123

예상되는 결과:

a "removeme" b +removeme+ c *removeme#d+removeme~ .123
a  b  c d .123

답변1

특별한 경우에는 다음을 수행할 수 있습니다.

  • 원하지 않는 모든 문자를 알려진 단일 문자(세트의 일부)로 바꾸십시오.
  • 이 대체 문자의 두 인스턴스 사이의 모든 문자열을 제거합니다.
echo 'a "removeme" b +removeme+ c *removeme#d+removeme~ .123' | sed -e '/\W/p; s/["+*#~]/#/g ; s/#[^#]\+#//g'
a "removeme" b +removeme+ c *removeme#d+removeme~ .123
a  b  c d .123

를 보존하려고 하므로 ."단어가 아닌" 클래스에는 "."이 포함되어 있으므로 사용할 수 없습니다. 어떤 희생을 치르더라도 명시적인 문자 목록을 제공하지 않으려면 다음을 수행할 수 있습니다.

  • 점을 사용하기 어려운 단어 문자(가시, 슬래시-O, 악센트 a/e/i/o/u 또는 그리스어/키릴 문자)로 바꾸십시오.
  • [:punct:]를 사용하여 위 식을 적용합니다.
  • 복구 지점.

답변2

모든 점을 개행 문자로 변경하세요. 공백이 보장되고 구두점이 아닌 문자가 보장됩니다. 그런 다음 두 구두점을 욕심 없이 일치시키는 간단한 문제입니다.

$  echo 'a "removeme" b +removeme+ c *removeme#d+removeme~ .123' |
   sed -e 'p
     y/./\n/
     s/[[:punct:]][^[:punct:]]*[[:punct:]]//g
     y/\n/./
   '

a "removeme" b +removeme+ c *removeme#d+removeme~ .123
a  b  c d .123

참고: 이는 모두 Posix sed 내에 있습니다.

답변3

Perl은 이와 같은 상황을 처리하는 데 능숙합니다. 점을 포함하지 않는 구두점 클래스를 생성하기 위해 부정 예측을 사용합니다:

echo '......' |
perl -lpe '
 print;
 $p = qr/(?!\.)[[:punct:]]/;
 s/$p.*?$p//g;
' 

관련 정보