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;
'