마지막 문자를 삭제하면서 한 문자의 모든 항목을 바꾸는 (sed) 정규식을 만드는 방법은 무엇입니까?

마지막 문자를 삭제하면서 한 문자의 모든 항목을 바꾸는 (sed) 정규식을 만드는 방법은 무엇입니까?

나는 다음 문제로 어려움을 겪고 있습니다. 정규식을 테스트하기 위해 Mac 터미널에서 다음과 같은 명령을 사용하고 있습니다.

echo 'inputstring' | sed (-E) '/s///g'

다음과 같은 정규식을 만들려고 합니다.

  • 단어가 문자 'o'로 끝나는 경우에만 다음과 같습니다.
  • 이 단어 끝 'o'를 삭제합니다.
  • 이 단어에서 문자 'i'를 모두 'a'로 바꿉니다.

이 경우 입력 문자열은 다음 과 같 filo fililo felo fale으며 예상되는 출력은 다음과 같습니다.fal falal fel fale

삭제나 교체를 수행하는 정규식을 만들 수 있지만 이를 결합하는 방법은 알 수 없습니다. 그 사이에 세미컬럼을 넣으면 조건부 부분을 어떻게 넣어야 할지 모르겠네요.

또한 '단어의 끝' 위치를 정의하는 데 어려움을 겪고 있습니다. 사용했지만 \b작동하지 않는 것 같습니다( $문자열 끝과 달리).

답변1

나는 sed이것을 사용하지 않을 것이지만 이것이 학습 연습이라면 sed다음과 같은 루프를 수행하십시오.

sed -E 's/$/ /
  :a
  s/i([[:alnum:]]*o[^[:alnum:]])/a\1/
  ta
  s/([[:alnum:]]*)o([^[:alnum:]])/\1\2/
  ta
  s/ $//'
  • 첫 번째 줄 끝에 공백을 추가하여 줄 끝을 단어 끝처럼 처리할 수 있습니다. 마지막 줄은 나중에 해당 공백을 제거합니다.
  • s3행의 명령은 로 끝나는 단어에서 가 있는 단어를 검색 하여 io바꿉니다 a. 명령 은 모든 끝 단어에서 모두에 대해 이를 반복하기 위해 t표시로 다시 돌아갑니다 .:aio
  • 이제 다섯 번째 줄에서는 끝 부분 o과 또 다른 루프가 제거됩니다. 로 끝나는 단어에서는 oo둘 다 제거됩니다. 이것이 바람직한지 여부는 불분명합니다.

참고용으로 만 일치하는 부분만 보존하고 나머지는 버린다는 의미 의 명령 옵션을 sed지원하는 버전 을 사용합니다 . 또한 보유 공간의 내용으로 교체할 교체 방법도 알고 있습니다 . 이렇게 하면 작업이 한 줄로 처리됩니다.os\h

sed -E ':a;h;s/([[:alnum:]]*)o($|[^[:alnum:]])/\1\2/o;T;y/i/a/;x;s//\h/;ba'

답변2

이러한 경우에는 더 정확하고 유연합니다.

awk '{ for(i=1;i<=NF;i++) 
       if ($i~/o$/) { sub(/o$/,"",$i); gsub("i","a",$i) } }1' <<<"filo fililo felo fale"

출력:

fal falal fel fale

대안파이썬명령줄 접근 방식:

python -c 'import sys,re; s = sys.stdin.read().strip(); 
print(re.sub(r"\b(\S+)o\b", lambda m: m.group(1).replace("i","a"), s))' <<<"filo fililo felo fale"
fal falal fel fale

답변3

이것이 가능한지 확실하지 않지만 sed(아마도 그렇지 않을 것이라고 생각합니다), Python을 사용하면 정말 쉽습니다! 원하는 작업을 정확하게 수행하는 스크립트는 다음과 같습니다.

#!/usr/bin/env python2
# -*- coding: ascii -*-
"""modify_strings.py"""

import sys
import re
import fileinput

# Iterate over lines of input
# (either read from files or from stdin)
for line in fileinput.input():

    # Split each line into tokens and preserve whitespace
    tokens = re.split(r'(\s+)', line)

    # Iterate over tokens
    for token in tokens:

        # If a word ends in 'o' then
        # perform the desired transformation
        if token.endswith('o'):
            token = token[:-1].replace('i', 'a')

        # Print out each token
        sys.stdout.write(token)

다음과 같이 실행할 수 있습니다.

echo 'filo fililo felo fale' | python modify_strings.py

그리고 (원하는 대로) 다음과 같은 출력을 생성합니다.

팔 팔팔 펠 팔레

정말로 참여하고 싶다면 sed약간의 쉘 스크립팅으로 이를 강화하여 원하는 것을 얻을 수 있을 것입니다. 이는 다음 bash스크립트 와 유사할 수 있습니다 .

#!/usr/bin/env bash

# modify-strings.bash

for word in "$@"; do
    if grep -q 'o$' <<<"${word}"; then
        echo -n "${word} " | sed -e 's/i/a/g' -e 's/o$//';
    else
        echo -n "${word} ";
    fi;
done
echo

이 스크립트를 다음과 같이 호출할 수 있습니다.

bash modify-strings.bash filo fililo felo fale

관련 정보