sed 代替使用が期待どおりに機能しません。

sed 代替使用が期待どおりに機能しません。

大容量ASCIIテキストファイルで検索/置換機能を実行する必要があります。入力ファイルからの短い抜粋:

gene_id "MSTRG.1";
gene_id "MSTRG.1";
gene_id "MSTRG.2";
gene_id "MSTRG.3";

このMSTRG文字列は、テンプレートファイル内の他のIDに置き換えられます。

MSTRG.1 AT1G01030
MSTRG.2 AT1G01010
MSTRG.3 AT1G01035

単純なwhileループは、テンプレートの各行を繰り返して置き換えます。

while read bef aft
do
  echo "Searching for $bef"
  echo "Replacing with $aft"
  sed "s/$bef/$aft/g" input > output
done < template

MSTRG.2その後、アイテムは正しく置き換えられますが変更されていませんMSTRG.1。出力は次のとおりです。

gene_id "MSTRG.1";
gene_id "MSTRG.1";
gene_id "AT1G01010";
gene_id "AT1G01035"; 

修正する

これが私がしたことです。

while read bef aft
do
  sed -i "s/$bef/$aft/g" input
done < template

ベストアンサー1

問題は、ループを繰り返すたびに出力ファイルを削除して最新の変更のみを残し、output以前の変更は残らないことです。

代わりに、templateファイルを一連のsedコマンドに簡単に変換できます。

$ awk '{ printf("s/%s/%s/g\n", $1, $2) }' template
s/MSTRG.1/AT1G01030/g
s/MSTRG.2/AT1G01010/g
s/MSTRG.3/AT1G01035/g

...その後、ファイルに適用します。

$ awk '{ printf("s/%s/%s/g\n", $1, $2) }' template | sed -f - input
gene_id "AT1G01030";
gene_id "AT1G01030";
gene_id "AT1G01010";
gene_id "AT1G01035";

一部の実装では、標準入力の意味をsed認識しません。-このタイプのこの方法を使用するには、にsed置き換えます。-f --f /dev/stdin

または、以下からすべての操作を実行できますawk

$ awk 'FNR == NR { pat[$1] = $2; next } { for (p in pat) gsub(p, pat[p]); print }' template input
gene_id "AT1G01030";
gene_id "AT1G01030";
gene_id "AT1G01010";
gene_id "AT1G01035";

上記のすべてのバリアントは、最初の列の内容を次のtemplateように使用します。正規表現、意味.(点)が一致どの特徴。

おすすめ記事