sed:パターンを変数リストに一度だけ置き換える

sed:パターンを変数リストに一度だけ置き換える

私はsedを初めて使用し、毎回パターンを別の変数に置き換える方法を知りたいです。

以下のtxtファイルがあります。

@K3KFV:1:1109:11598:25872
@K3KFV:1:2101:22577:15247
@K3KFV:1:1110:13477:13178
@K3KFV:1:2113:23585:6859... (etc)

合計200本の異なるラインがあります。また、他のファイルがあります。

ASF356_KB822565.1:1065516-1065795
TAGGTCAAGCCCTCGGTCTATTAGTATTGGTCAGCTTAATACATTGCTGCACTTACACCT
CCAACCTATCTACCTTGTTGTCTTCAAGGGACCTTACTCACTTGCGTTTTGGGATATCTT
 
ASF356_KB822565.1:1065796-1066075
CGGATAGGGACCGAACTGTCTCACGACGTTCTGAACCCAGCTCGCGTACCGCTTTAATGG
GCGAACAGCCCAACCCTTGGGACCTACTTCAGCCCCAGGATGCGATGAGCCGACATCGAG
 
ASF356_KB822565.1:1066076-1066355
CCTTTTGCCTTTACACTCTTTGAATGGTTTCCAATCATTCTGAGGTGACCTTCGAGCGCC
TCCGTTACTCTTTTGGAGGCGACCGCCCCAGTCAAACTGCCCGCCTGACATTGTCCTTCA

また、「ASF....」の200個のインスタンスも含まれています。

私が望むのは、「ASF...」を含む行を「@K3KFV:.....」の行に置き換えることです。

@K3KFV:1:1109:11598:25872
TAGGTCAAGCCCTCGGTCTATTAGTATTGGTCAGCTTAATACATTGCTGCACTTACACCT
CCAACCTATCTACCTTGTTGTCTTCAAGGGACCTTACTCACTTGCGTTTTGGGATATCTT

@K3KFV:1:2101:22577:15247
CGGATAGGGACCGAACTGTCTCACGACGTTCTGAACCCAGCTCGCGTACCGCTTTAATGG
GCGAACAGCCCAACCCTTGGGACCTACTTCAGCCCCAGGATGCGATGAGCCGACATCGAG

@K3KFV:1:1110:13477:13178
CCTTTTGCCTTTACACTCTTTGAATGGTTTCCAATCATTCTGAGGTGACCTTCGAGCGCC
TCCGTTACTCTTTTGGAGGCGACCGCCCCAGTCAAACTGCCCGCCTGACATTGTCCTTCA

これはこれまで私のシェルスクリプトです。

input="K3KFVfile.txt"

while IFS= read -r title
do
        sed '/ASF/c'$title'' ASF_file
done < "$input"

しかし、@K3KFV 200行を与えるのではなく...すべてのASF行がすべての@K3KFV行に置き換えられたので、40000行を得ました。

続行する前に、sedを使用してパターンを変数に一度だけ変更する方法はありますか?この場合、sedは正しいコマンドですか?

答え1

sedのGNU実装がある場合(capital)コマンドを使用できますRGNU sed 関連コマンドASF- 2番目のファイルから-で始まる行と一致するたびに、最初のファイルの行を読み込み、挿入します。次に、一致する行を削除します。

$ sed '/^ASF/{
R K3KFVfile.txt
d
}' ASF_file
@K3KFV:1:1109:11598:25872
TAGGTCAAGCCCTCGGTCTATTAGTATTGGTCAGCTTAATACATTGCTGCACTTACACCT
CCAACCTATCTACCTTGTTGTCTTCAAGGGACCTTACTCACTTGCGTTTTGGGATATCTT

@K3KFV:1:2101:22577:15247
CGGATAGGGACCGAACTGTCTCACGACGTTCTGAACCCAGCTCGCGTACCGCTTTAATGG
GCGAACAGCCCAACCCTTGGGACCTACTTCAGCCCCAGGATGCGATGAGCCGACATCGAG

@K3KFV:1:1110:13477:13178
CCTTTTGCCTTTACACTCTTTGAATGGTTTCCAATCATTCTGAGGTGACCTTCGAGCGCC
TCCGTTACTCTTTTGGAGGCGACCGCCCCAGTCAAACTGCCCGCCTGACATTGTCCTTCA

必要に応じて、次のように1行で書くことができます。

sed -e '/^ASF/{R K3KFVfile.txt' -e 'd}' ASF_file

あるいは、awkの使用を検討することもできます。

awk 'NR==FNR{K[FNR] = $0; next} /^ASF/{$0 = K[++n]} 1' K3KFVfile.txt ASF_file

答え2

この答えは少し即興で書かれています。@スチールドライバ

ASF_fileの空行が実際に空の場合(空白なし)、このawkは機能します。

awk '
    NR == FNR {x[FNR] = $0; next}
    {$1 = x[FNR]; print}
' K3KFVfile.txt RS='' ORS='\n\n' FS='\n' OFS='\n' ASF_file

2番目のファイルを読み始める前に、レコードとフィールドの決定方法を制御するためにいくつかのawk変数を変更しました。私は通常このようなスタイルのファンではありませんが、ここではうまくいきます。このGNU awkバージョンはもう少しきれいです。

gawk '
    NR == FNR {x[FNR] = $0; next}
    ENDFILE {RS = ""; ORS = "\n\n"; FS = OFS = "\n"}
    {$1 = x[FNR]; print}
' K3KFVfile.txt ASF_file

答え3

使用awk:

awk '/^ASF/ {getline < "@K3FVfile.txt"};1' ASF_file

同じものPerl

perl -pe 's/^ASF.*/<STDIN>/se' ASF_file < @K3FVfile.txt

POSIXly sedを使用してください。

sed -n '/\n/bh
  1{
    :k3
      H;1h;n
    /^@K3KFV/bk3
  }
  /^ASF/g
  P;/\n.*\n/D
  s/.*\n//;th
  d;:h
  h
' @K3FVfile.txt ASF_file

Pythonでリストを理解する:

python3 -c 'import sys;a,b = sys.argv[1:]
with open(a) as f, open (b) as g:
  print(*[next(f) if l.startswith("ASF") else l for l in g],sep="",end="")
' @K3FVfile.txt ASF_file

出力:

@K3KFV:1:1109:11598:25872
TAGGTCAAGCCCTCGGTCTATTAGTATTGGTCAGCTTAATACATTGCTGCACTTACACCT
CCAACCTATCTACCTTGTTGTCTTCAAGGGACCTTACTCACTTGCGTTTTGGGATATCTT
 
@K3KFV:1:2101:22577:15247
CGGATAGGGACCGAACTGTCTCACGACGTTCTGAACCCAGCTCGCGTACCGCTTTAATGG
GCGAACAGCCCAACCCTTGGGACCTACTTCAGCCCCAGGATGCGATGAGCCGACATCGAG
 
@K3KFV:1:1110:13477:13178/
CCTTTTGCCTTTACACTCTTTGAATGGTTTCCAATCATTCTGAGGTGACCTTCGAGCGCC
TCCGTTACTCTTTTGGAGGCGACCGCCCCAGTCAAACTGCCCGCCTGACATTGTCCTTC

関連情報