文字列内の一部の文字を別の文字に置き換える


278

AxxBCyyyDEFzzLMNのような文字列があり、出現するすべてのxy、およびz_に置き換えたい。

どうすればこれを達成できますか?

私はそれecho "$string" | tr 'x' '_' | tr 'y' '_'がうまくいくことを知っていますが、パイプを使用せずに一度にそれをやりたいです。


あなたが連続したXの、Yのまたはzの任意の順序を交換したかった1アンダースコア、またはあなたが交換したいんでした 1アンダースコアでのx、y、またはzの?また、混合シーケンスについてはどうAxyzBですか?アンダースコア3つまたは1つ?
デビッドZ

tr '[xyz]'[および]も置き換えます。引数は、単純に文字のリストでなければなりません(のような範囲a-zは問題ありませんが、一部の実装では、のようなPOSIX文字クラスです[:digit:])。
Tripleee

回答:


327
echo "$string" | tr xyz _

各発生に代わるxyまたはz_与えて、A__BC___DEF__LMNあなたの例では。

echo "$string" | sed -r 's/[xyz]+/_/g'

あなたの例ではx、繰り返し出現する、、yまたはzを単一の_に置き換えA_BC_DEF_LMNます。


19
Macでは、次のものが得られました:sed:不正なオプション-r使用法:sedスクリプト[-Ealn] [-i拡張子] [ファイル...] sed [-Ealn] [-i拡張子] [-eスクリプト]。 .. [-f script_file] ... [file ...]
カタノワー

文字を含む,[]{}()~文字列があります。エスケープされた各特殊文字に置き換えたいのですが、'\'どうすればこれをワンショットで実行できますか?
inckka 2014

2
@halakala Macには、わずかに異なるバージョンのsedが同梱されています。この質問を参照してください:unix.stackexchange.com/questions/13711/… 代わりに、Homebrewパッケージマネージャーで「gnu-sed」をインストールしてから、gsedバイナリを使用できます。$ brew install gnu-sedその後$ gsed -r 's/[xyz]+/_/g'
John Kary

6
* BSD(したがって、OSX)では、sed -E(基本的に)sed -r多くのLinuxディストリビューションと同等です。使用sed 's/[xyz][xyz]*/_/g'する場合、オプションは必要ありません。もちろん、これは同等tr -s xyz _なので、sedここで実際に必要なものはありません。
Tripleee

@inckka trそのために使用することはできません。 sed 's/[][{}()~,]/\\&/g'ただし、フォローアップの質問がある場合は、新しい質問をしてください(もちろん、参照用にここにリンクしてください)。なお、,及び~(ただし正規表現メタ文字でない~に拡張されます$HOMEバッシュ、およびいくつかの他のシェルによっていくつかの位置では、そうでないshが)。
Tripleee

285

Bashパラメータ拡張の使用:

orig="AxxBCyyyDEFzzLMN"
mod=${orig//[xyz]/_}

7
悪い代替
アレクセイ

1
@Alexey、私の例は私のために機能します(bash 4.3.11(1)-release)。を使用していることを確認してくださいbash。他のシェルは機能しない可能性があります(一部は機能します)。
マシューFlaschen 2014

@MatthewFlaschenに感謝します。これは、bashスクリプトで絶対パスのsed置換を実行するために必要なものでした(/を\ /で置き換えると、sedはそれを受け入れます)。
Ryan G、

1
@RyanG sedbashに組み込みの置換がある場合に使用するのはなぜですか?
MestreLion、2015年

@MestreLion間違っている可能性がありますが、一連のファイル内の標準変数名を絶対パスに置き換える必要がありました。そのため、sed inplace置換を使用していました。ただし、コマンドでエスケープせずに「/」を付けることはできません。私はbashで操作をつなぎ合わせていました。これはbashで文字列を操作する最良の方法ではないでしょうか?
ライアンG

111

このリンクは役に立ちます:

http://tldp.org/LDP/abs/html/string-manipulation.html

一般に、

$ substringの最初の一致を$ replacementで置き換えるには:

${string/substring/replacement}

$ substringのすべての一致を$ replacementで置き換えるには:

${string//substring/replacement}

編集:これは$ stringという名前の変数に適用されることに注意してください。


16
これは、リテラル文字列ではなく、「string」という名前変数で機能することに注意してください。
mattdm 2016年

1
リファレンスが含まれているため、最も役立ちます。
Os3

最善かつ最短のソリューション。
ノースツリー

8
read filename ;
sed -i 's/letter/newletter/g' "$filename" #letter

^これらを必要なだけ使用して、独自のBASIC暗号化を作成できます


5

これは、複数の連続するオカレンスを1つに置き換えるシェルパラメーター展開のソリューション_です。

$ var=AxxBCyyyDEFzzLMN
$ echo "${var//+([xyz])/_}"
A_BC_DEF_LMN

パターンが拡張パターンマッチングを必要とすることに注意してください。+(pattern)

shopt -s extglob

または、-s( "squeeze")オプションを使用してtr

$ tr -s xyz _ <<< "$var"
A_BC_DEF_LMN
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.