如果某个模式存在于另一个文件中,如何使用 awk 替换一个文件中的字符串

如果某个模式存在于另一个文件中,如何使用 awk 替换一个文件中的字符串

我有一个数据文件A.txt(字段分隔符 = \t):

Well    Well Type   Well Name   Dye Target  
A1      Unknown     HIGH-001    FAM ViroFAM                 
A1      Unknown     HIGH-001    HEX ViroHEX

和一个模板文件B.txt

kit
Software Version = NOVA_v1
Date And Time of Export = 07/02/2020 13:44:11 UTC
Experiment Name =
Instrument Software Version =
Instrument Type = CFX
Instrument Serial Number =
Run Start Date =
Run End Date =
Run Operator =
Batch Status = VALID
Method = Novaprime
Date And Time of Export,Batch ID,Sample Name,Well,Sample Type,Status,Interpretive Result,Action*,Curve analysis
,taq,205920777.1,A01,Unkn-01
,taq,neg5,A02,Unkn-09
,,,,,,,,,,
*reporting.

我想打印替换with=第二行中的值,但前提是该模式存在于 的第五列中。B.txtVIRO_v1ViroHEXA.txt

为了做到这一点,我开始了类似的事情:

awk -F'\t' '
  FNR==NR{ a[NR]=$2; next }
  $1=="Software Version"{ print $0,"VIRO_v1"; next }
  1
' B.txt FS=" =" B.txt > result.txt

但我没有弄清楚 的部分A.txt。你知道该怎么做吗?

答案1

awk -F'\t' '
  NR==FNR{ if ($5=="ViroHEX"){ viro=1 } next }
  viro && $1=="Software Version"{ $2="VIRO_v1" }
  1
' A.txt FS=" = " OFS=" = " B.txt > result.txt

如果第一个字段等于并且出现在第一个文件的第 5 列中的任何位置,则这会将第二个文件中的第二个字段 ( NOVA_v1)替换。VIRO_v1Software VersionViroHEX

我假设第二个文件的字段分隔符是<space>=<space>(不是制表符)。

答案2

如同贝恩鲍什解,但要更加小心我们实际匹配和插入的内容。

awk -F '\t' '$5 == "ViroHEX" { found = 1; exit } END { exit !found }' A.txt &&
sed '2 s/=.*/= VIRO_v1/' B.txt

这首先用于awk确定确切的字符串是否ViroHEX出现在文件中任何行的第五个制表符分隔字段中A.txt。它不会读取超出必要范围的文件内容,并以稍后用于有条件运行的退出状态退出sed

sed命令将=第二行第一个字符中的所有内容替换B.txt为字符串= VIRO_v1

如果A.txt文件不包含ViroHEX第五列,则不会生成任何输出。

以下变体始终生成B.txt文件,可能在第二行完成替换:

if awk -F '\t' '$5 == "ViroHEX" { found = 1; exit } END { exit !found }' A.txt
then
    sed '2 s/=.*/= VIRO_v1/'
else
    cat
fi <B.txt

如果您不想修改第 2 行,而是想修改 行Software Version = ...,则将调用中使用的表达式更改为sedinto

s/^\(Software Version = \).*/\1 VIRO_v1/

答案3

以我的愚见,一个更简单的解决方案。不幸的是,除了 awk 之外,它还使用其他工具。

awk '{print $5}' A.txt | grep -q VIROHEX && sed 2s/NOVA/VIRO/ B.txt

&& 之前的部分实现条件,程序sed替换文件 B.txt 中的文本。

编辑:谢谢 AdminBee 指出我的解决方案是懒惰的。更好的:

awk '{print $5}' A.txt | grep -q VIROHEX && sed '2s/=.*/= VIRO_v1/' B.txt

相关内容