如何用另一个文件中的值替换文本块中的特定文本?

如何用另一个文件中的值替换文本块中的特定文本?

我有重复的文本行块:

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  

要求每当baby遇到该术语时,它就被第二个文件中的连续术语替换。例如,对于first baby,它被替换为:

I love D1  

对于第二个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 四行,您将得到:

$ ./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

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

每次 file1 中的 field3=baby 将 $3 替换为 file2 的一行。

编辑:

如果我理解得很好,你在 file1 中的行看起来像:

Ilovepeaches
Ilovemybeautifulbabygirl
Ilovewatermelon

你想用 file2 中的一行替换每个婴儿

所以,你可以尝试这样的方法:

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

使用 awk,file2包含替换文本和file1重复文本:

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

请注意,file2这里的 是第一个文件参数,而不是file1.

解释:

  • FNR == NR对于 awk 读取的第一个文件来说是正确的,所以file2这里。对于该文件,我们将每一行保存在一个数组中,按行号索引
  • 对于第二个文件,我们保留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

相关内容