テキストブロック内の特定のテキストを他のファイルの値に置き換えるには?

テキストブロック内の特定のテキストを他のファイルの値に置き換えるには?

テキスト行ブロックを繰り返しました。

I love banana  
I love mango  
I love papaya  
I love guava  
I love peaches  
I love baby  
I love watermelon  
I love banana  
I love mango  
I love papaya  
I love guava  
I love peaches  
I love baby  
I love watermelon  
I love banana  
I love mango  
I love papaya  
I love guava  
I love peaches  
I love baby  
I love watermelon  
I love banana
I love mango  
I love papaya  
I love guava  
I love peaches  
I love baby  
I love watermelon  
I love banana  
I love mango  
I love papaya  
I love guava  
I love peaches  
I love baby  
I love watermelon  

次のテキストを含む他のファイルがあります。

D1  
D2  
D3  
D4  
D5  

用語が見つかるたびに、baby2番目のファイルの連続語で置き換える必要があります。たとえば、first の場合、次のようbabyに置き換えられます。

I love D1  

2番目のエントリの場合は、ファイルの最後までbaby置き換えられます。D2以下に失敗した試みの概要を示します(非常にカジュアルに言及されています...申し訳ありません)。誰でも私を助けることができますか?

for x in `cat test1.txt|tr -d '\r'`; do awk '{gsub(/baby/,'"$x"')}' test3.txt ; done

for x in `cat test1.txt|tr -d '\r'`; do sed -i 's/baby/$x/g' test3.txt ; done

sed "0,/baby/{s/baby/$x/}" "test3.txt"  

for x in `cat test1.txt|tr -d '\r'`; do awk 'NR==1,/baby/{sub(/baby/,'"$x"')} print' test3.txt ; done  
awk '/^baby$/&&getline<"test1.txt"||1' test3.txt

awk 'NR==FNR{Arr[NR]=$0;next}{if($0==baby){i++;print Arr[i]}else{print}}' test3.txt test1.txt

#!/bin/bash

while read -r line; do  
    if [[ "$line"  == baby ]]; then  
        sed -n '1p' test3.txt  
        sed -i".bup" '1d' test3.txt   
    else  
        echo "$line"  
    fi    
done < test1.txt

答え1

file2.txt発生回数よりも入力行が多いと確信している場合は、baby簡単なスクリプトを使用できます。

awk 'BEGIN{ sf="file2.txt"}
     /baby/ {  getline var <sf; gsub(/baby/,var,$0) }
print
' file1.txt

ただし、より強力なスクリプトは、読み取り値にエラーがfile2.txtあるかどうかを確認したり、スクリプトがfile2.txtの終わりに達したときに最初に戻ることができます。

awk 'BEGIN{ sf="file2.txt"}
/baby/{
         # If at the end of second file, rewind to start.
         while( (test=(getline var <sf)) != 1 ){
            if( test==-1 ){ print "Error: file ",sf,":",ERRNO; exit 1 }
            if( test==0  ){ close(sf); continue }
                # This script should never get up to here
                print "Unexpected error"; exit 2
            }
         sub(/baby/,var ,$0)
     }
1
' file1.txt

file2.txt に D1、D2、D3、D4 の 4 行しか含まれていない場合は、次のような結果が表示されます。

$ ./script
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D1
I love watermelon
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D2
I love watermelon
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D3
I love watermelon
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D4
I love watermelon
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D1
I love watermelon

答え2

別の奇妙な

awk -v f='file2' '$3=="baby"{getline $3 <f}1' file1

file1のfield3 = babyが$ 3をfile2の1行に置き換えるたびに。

編集する:

私がよく理解しているなら、file1の行は次のようになります。

Ilovepeaches
Ilovemybeautifulbabygirl
Ilovewatermelon

各赤ちゃんをfile2の1行に置き換えたいです。

したがって、次のように試すことができます。

awk -v search='baby' -v f='file2' '
  $0 ~ search {
     split($0,lign,search)
     getline <f
     $0=lign[1]$0lign[2]
}1' file1

出力:

Ilovepeaches
IlovemybeautifulD3girl
Ilovewatermelon

答え3

file2代替テキストやfile1繰り返しテキストを含むawkを使用する:

awk 'FNR == NR {baby[NR] = $0; next} /baby/ {count++; $NF = baby[count]} 1'  file2 file1

これはfile2最初のファイルパラメータですfile1

説明する:

  • FNR == NRこれはawkが読み取る最初のファイルに適しているので、file2ここにあります。このファイルの場合は、各行を行番号で索引付けされた配列に保存します。
  • 2番目のファイルの場合は、count一致する各行を保持babyし、配列からその数のエントリを取得し、最後のフィールドをそのエントリに置き換えます。

私が得た結果は次のとおりです。

~ awk 'FNR == NR {baby[NR] = $0; next} /baby/ {count++; $NF = baby[count]} 1'  file2 file1
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D1
I love watermelon
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D2
I love watermelon
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D3
I love watermelon
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D4
I love watermelon
I love banana
I love mango
I love papaya
I love guava
I love peaches
I love D5
I love watermelon

関連情報