(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/ $//'
  • 最初の行では、行の末尾を他の単語の終わりと同じように処理できるように、末尾にスペースを追加しました。最後の行は後で対応するスペースを削除します。
  • 3行目のコマンドは、sで終わる単語を検索してに置き換えます。コマンドはトークンに戻り、すべての終わりの単語のすべての単語に対してこの操作を繰り返します。ioat:aio
  • 5行目では、エンディングとo別のループを削除します。で終わる単語はooすべて削除されます。これが私たちが望むものであるかどうかはわかりません。

ちなみに私はsedcommand ooptions をサポートするバージョンを使用しておりs、一致する部分だけ保持して残りは捨てます。また\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コマンドライン方法:

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

関連情報