我有一个属性文件,其中包含数百行,如下所示mainfile.txt
:
del.frequencyMinutes = 360
del.gracePeriodMinutes = 4320
vol.operationsEnabled = true
vol.multiFolderContainer = false
pool.capacity.differential = 30
pool.cpu.differential = 30
vol.single.pool.maxVolSize = 100
vol.multi.pool.maxVoluSize = 20
我想要一个小文件,我想根据一些不同的测试设置保留一些更改,如下所示change.txt
:
del.frequencyMinutes = 1440
del.gracePeriodMinutes = 2000
当change.txt
中的属性(字段$1
)与主文件中的属性匹配时,它们的值应覆盖到主文件中。 我尝试了以下代码,但缺少一些重要的东西:
awk -F= 'NR==FNR{val1=$1;val2=$2;next}{ if ($1==val1) printf $1" = "val2;else if ($1 != val1) print $0}' changes.txt mainfile.txt
我看到它只将change.txt
中的第二个属性行注入mainfile.txt
而缺少第一个属性行。所以
- 如何添加所有
change.txt
行 - 上面的代码只打印结果,不写入主文件,那么我怎么能永久写入主文件呢?
我不太擅长 awk/shell 脚本,所以我感谢您解释我在这里做错了什么
我会按照以下方式使用 GNUAWK
来完成此任务
awk 'BEGIN{FS=OFS=" = "}NR==FNR{arr[$1]=$2;next}($1 in arr){$2=arr[$1]}{print}' changes.txt mainfile.txt
这对changes.txt
del.frequencyMinutes = 1440
del.gracePeriodMinutes = 2000
和mainfile.txt
del.frequencyMinutes = 360
del.gracePeriodMinutes = 4320
vol.operationsEnabled = true
vol.multiFolderContainer = false
pool.capacity.differential = 30
pool.cpu.differential = 30
vol.single.pool.maxVolSize = 100
vol.multi.pool.maxVoluSize = 20
给出输出
del.frequencyMinutes = 1440
del.gracePeriodMinutes = 2000
vol.operationsEnabled = true
vol.multiFolderContainer = false
pool.capacity.differential = 30
pool.cpu.differential = 30
vol.single.pool.maxVolSize = 100
vol.multi.pool.maxVoluSize = 20
说明:我将字段分隔符(FS
)和输出字段分隔符(OFS
)都设置为=
,因此在更改一个字段行后仍然property = value
,然后在处理第一个文件(NR==FNR
)时,我将键属性的数组arr
值设置为其值。 使用next
,因此不执行其他操作。在除第一个文件外的所有文件中:如果属性(第一个字段,$1
)是arr
键之一,则将值(第二个字段,$2
)设置为该键的值,始终print
整行。
(在Gawk 4.2.1中测试)
当输入文件中有多个行时,您将覆盖以前的val1
和val2
值。通常和非常常见的解决方案是将行读入关联数组。
awk -F= 'NR==FNR { a[$1] = $0; next }
$1 in a { print a[$1]; next } 1' changes.txt mainfile.txt >temp
mv temp mainfile.txt
当它看到该文件中的第一个字段时,这将打印来自changes.txt
的输入,否则将打印原始输入行。结果将写入一个临时文件,然后我们重命名该文件以将其移回原始mainfile.txt
之上。
这里的-F =
是可疑的; 也许将其取出,和/或在检查它是否在a
之前规范化$1
周围的空格。Awk(或几乎所有通用编程语言)中的字符串比较认为,如果字符串在文本周围具有不同数量的空格,则字符串是不同的。
最后唯一的1
是常见的 Awk 速记,意思是"如果你走到这一步,只需打印当前的输入行"。