標準入力に正規表現を適用

標準入力に正規表現を適用

プログラミングでは、一般的な表現

最も一般的な形式の1つは次のとおりです。

newText = text.replace( /regex/, 'replacementString' )

もし標準入力textであり標準出力はいnewText、上記のコードに対応するbashは何ですか?

答え1

簡単な使用のために、次のことができます。

newText=${text/SEARCH/replacement}

説明したようにここしかし、より複雑な表現の場合、sedはAlexが以前に説明したのと同じです。

答え2

最も直接的な答えはsedコマンドs。正規表現構文を次に変換する必要があります。基本正規表現、置換は各行に連続して適用されます。\1through を使用すると、\9元の文字列で括弧で囲まれたグループを参照できます。すべての項目を置き換えるには、修飾子を追加してくださいg。それ以外の場合は、最初の項目のみが置き換えられます。

sed -e 's/basic regexp/replacement string/g'

より柔軟なユーティリティは次のとおりです。アッ。デフォルトでは入力を1行ずつ処理しますが、-vRS=…)を使用してレコード区切り文字を変更できます。このsub関数は単一の交換を実行し、gsubすべての項目を交換します。置換文字列は文字通り解釈されます。ただし、\括弧&で囲まれたグループを参照したい場合とmatch機能subtringを使用できます。

awk '{gsub(/regexp/, "replacement string")}'

Bashには正規表現マッチングのサポートが組み込まれています。[[ text =~ regexp ]]配列に保存されている一致する部分文字列を使用して代替テキストを設定できますBASH_REMATCH。入力を使用readまたは取得しcatprintf出力をエクスポートします。次の擬似コードは複数の置換を実行します(警告、テストされていません。コードは通常通り左から右に複数の置換を実行する必要があります。正しくなることを願っています)。

# The end marker must not have a prefix that is a suffix of a match of the regexp,
# and must not start or end with a newline
end_marker='EOF'
text=$(cat; echo "$end_marker")
while [[ $text =~ regexp(.*)$ ]]; then
    printf %s%s "${text%"$BASH_REMATCH[0]"}" "replacement string"
    text=$BASH_REMATCH[$#BASH_REMATCH]
  fi
done
printf %s "${text%"$end_marker"}"

(説明するいくつかの単語:閉じるタグは、コマンドの置き換えによって末尾の改行文字が削除されるのを防ぐためです${text%"$BASH_REMATCH[0]"}^(.*)を取得します。 最初の A マッチングの代わりに、最後のマッチングの後にサフィックスを繰り返し、最後に閉じるタグを引いた残りのマッチングを印刷します。

ワイルドカード一致と制限付き代替テキスト機能に満足している場合、bashは${variable/pattern/replacement}すべてのエントリを置き換えるために最初のスラッシュを.doubleとして指定します。このオプションが設定されると、extglobパターンは正規表現の機能を持ちます(ただし、珍しい構文を使用します)。

答え3

  • man sed
  • sed s/regex/replacementString/g

答え4

sedと同じツールを使用できますが、awk私の考えでは、このツールは非常に古く、狭く定義された操作にのみ役立ちます。

より良いオプションは、STDINをPerlシングルライナーまたはスクリプトにリダイレクトすることです。 Perlの正規表現のサポートは非​​常に優れており、他のほとんどの言語もこれらとの互換性をサポートしています。 sedとawkをPerlに直接変換するa2pツールもあります。s2pPerlを使用すると、CPAN全体を使用して問題を解決できます。

Perlが気に入らない場合は、Pythonを使用して同様の機能を取得できます。

関連情報