sed/awk/etc を使用して、あるテキストファイルの奇数行を別のテキストファイルの対応する奇数行に置き換えます。

sed/awk/etc を使用して、あるテキストファイルの奇数行を別のテキストファイルの対応する奇数行に置き換えます。

テキストファイルの1行を別のテキストファイルの対応する行に置き換えたいと思います。

ファイル1の内容:

>line1  
GGG  
>line2  
AAA  
>line3  
TTT  
>line4  
CCC  
>line5  
CAT 

ファイル2の内容:

>name.A
CTGG  
>name.B
GACC  
>name.C
CTGG  
>name.D
GGAA  
>name.E
GCTA

2つのファイルの行数は同じです。最終ファイルは次のようにする必要があります。

>name.A  
GGG   
>name.B  
AAA  
>name.C  
TTT  
>name.D  
CCC  
>name.E  
CAT 

解決策が見つかりましたが見つからないようです。私は以下を試しました。

awk 'FNR==NR {data[FNR]=$0; next} (FNR%2==1){$0=data[FNR]}1' < File1 < File2

しかし、何も起こりませんでした。

どんな助けでも大変感謝します!

答え1

$ awk 'NR==FNR{a[NR]=$0; next} {print (FNR%2 ? $0 : a[FNR])}' file1 file2
>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT

より簡潔で効率的であるだけでなく、:-)上記のアプローチは、次の理由であなたが使用するアプローチよりも効率的です。

  1. $ 0に割り当てられていないため、awkはレコードをフィールドに再分割することを強制しません。
  2. 1印刷するかどうかを決定する前に、各行の2番目の条件()をテストしません。

また、入力リダイレクトを使用して awk ファイルを開かないでください。複数のファイルで機能せず(見つかったように)、FILENAMEを確認する機能がなくなります。

答え2

まず、ユーティリティを呼び出してpasteタブ区切りの行を並べ替えてから、エディタを呼び出して目的のsedデータ出力を取得することでpbmを実行できます。

$ paste File1 File2  | sed -ne '
    s/>.*\t//p
    s/\t.*//p
 '

出力

>name.A
GGG  
>name.B
AAA  
>name.C
TTT  
>name.D
CCC  
>name.E
CAT 

\t注:Posix sedはタブ文字を表すエスケープシーケンスを認識しません。私は目に見えない文字を強調するためにそれを使用します。したがって、\ tの代わりにテキストタブ文字を入れることができます。

実用性を加えるとPerl次のような文章になります。

$ perl -pe '$_=($_,$,.<STDIN>)[$.%2]' File1 < File2

答え3

awkコマンドはデフォルトで正しいです。不要なリダイレクトを削除してファイルの順序を変更すると機能します。

$ awk 'FNR==NR {data[FNR]=$0; next} (FNR%2==1){$0=data[FNR]}1' File2 File1
>name.A
GGG  
>name.B
AAA  
>name.C
TTT  
>name.D
CCC  
>name.E
CAT 

または、GNU sedとプロセス置換をサポートするシェルを使用してください。

$ sed -e '2~2{R /dev/stdin' -e 'd}' File2 < <(sed '1~2d' File1)
>name.A
GGG  
>name.B
AAA  
>name.C
TTT  
>name.D
CCC  
>name.E
CAT 

説明する:

  • sed '1~2d' File1File1から奇数行を削除する

  • < <(...)stdinを介して結果を入力する

  • sed -e '2~2{R /dev/stdin' -e 'd}' File2stdinから一度に1行ずつ読み込み、次の偶数行の後にFile2に挿入するようにキューに入れてから、偶数行を削除します。

答え4

sedコマンドを使ってみましたが、うまくいきます。

for ((i=2;i<=10;i++));do j=`sed -n ''$i'p' f1`; k=`echo $j|sed -r "s/\s+//g"`;sed -i ""$i"s/.*/"$k"/g" f2;i=$(($i+1)); done

出力

>name.A
GGG
>name.B
AAA
>name.C
TTT
>name.D
CCC
>name.E
CAT

関連情報