私は途中で異なる変数を使って同じ拡張子を持つ2つのファイル名を変更しようとしています。
文書:cKO_mESC_Rep_1_H3K27Ac.gc_corrected.bam
INBAM=$(ls *_*.gc_corrected.bam)
INPUT=$(echo $INBAM | sed 's/_*.gc_corrected.bam/_input.gc_corrected.bam/g')
echo $INPUT
cKO_mESC_Rep_1_H3K27Ac_input.gc_corrected.bam
しかし、私の出力はcKO_mESC_Rep_1_input.gc_corrected.bam
エラーが何であるかを知っている人はいますか?たくさん試してみましたが、正しいキーワードで検索して回答を得られないことがあります。ありがとうございます!
答え1
ウェブサイトへようこそ。
「ワイルドカード」(別名」シェルボール")と一般的な表現使用前にsed
。
あなたの意図は、「アンダー.gc_corrected.bam
スコア、その後にランダムな数の文字と数字、その後に」パターンを変更することです_input.gc_corrected.bam
。残念ながら、あなたのsed
表現には2つの点で欠陥があります。
- 一致部分はシェルの一般的な「ワイルドカード」表記を使用します。ただし、ここには
sed
正規表現が必要であり、正規表現では*
いいえ「0個以上の文字で構成される文字列」を意味しますが、「前の文字の0個以上の繰り返し」を意味するため、式は.gc_corrected.bam
「0個以上の下線と次」で構成される文字列を置き換えます。パターンはで置き換えられます_input.gc_corrected.bam
。したがって、あなたの場合は、ファイル名のサフィックスの前の最後の下線を_input
。 - それにもかかわらず、実際のファイル名に複数のアンダースコアがある場合は、「任意の文字で構成される文字列」に一致するパターンにもアンダースコアが含まれ、一致する文字列の長さによっては望ましくない動作が発生する可能性があります。特に正規表現は欲が多く、注意深く構成しなけれ
_mESC_Rep_1_H3K27Ac
ば_input
。
あなたの場合、正しい正規表現は次のとおりです。
sed 's/_[^_]+\.gc_corrected\.bam/_input.gc_corrected.bam/g'
下線で始まり_
、その後に1つ以上の文字が続く文字列を置き換えます。下線が引かれていない([^_]+
)の後に、が.gc_corrected.bam
に置き換えられます_input.gc_corrected.bam
。
また参考にしてください正規表現では.
「すべての単一文字」(シェルワイルドカードで表されます?
)を表すため、リテラルと一致させるには.
この文字をエスケープする必要があります。もちろん、置換文字列には必要ありません。それ正規表現ではありません。