我有重复的文本行块:
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