使用 awk 从一个文件中读取并将属性注入到另一个文件中
Using awk to read from one file and inject properties into another file
我有一个 属性 文件,其中包含数百行,如下所示 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
中的属性(字段 </code>)与主文件中的匹配时,它们的值应该被覆盖到主文件中。我尝试了以下代码但遗漏了一些重要的东西:</p>
<pre><code>awk -F= 'NR==FNR{val1=;val2=;next}{ if (==val1) printf " = "val2;else if ( != val1) print [=12=]}' changes.txt mainfile.txt
我看到它只将 change.txt
中的第二 属性 行注入到 mainfile.txt
中,而缺少第一行。所以,
- 如何添加所有
change.txt
行
- 上面的代码只是打印结果,并没有写入主文件,那我怎么能永久写入主文件呢?
我不太擅长 awk/shell 脚本编写,所以如果你能解释一下我在这里做错了什么,我将不胜感激
当输入文件中有多行时,您正在覆盖 val1
和 val2
的先前值。通常且非常常见的解决方案是将行读入关联数组。
awk -F= 'NR==FNR { a[] = [=10=]; next }
in a { print a[]; next } 1' changes.txt mainfile.txt >temp
mv temp mainfile.txt
当它看到该文件中的第一个字段时打印来自 changes.txt
的输入,否则打印原始输入行。结果被写入一个临时文件,然后我们将其重命名以将其移回原始 mainfile.txt
.
之上
这里的-F =
是可疑的;也许把它拿出来,and/or 在检查它是否在 a
之前规范化 </code> 周围的空白。 Awk 中的字符串比较(或几乎所有 general-purpose 编程语言)将字符串视为不同,如果它们在文本周围有不同数量的空格。</p>
<p>最后一个 <code>1
是一个常见的 Awk shorthand,表示“如果你走到这一步,只需打印当前输入行。”
我会按照以下方式使用 GNU AWK
完成此任务
awk 'BEGIN{FS=OFS=" = "}NR==FNR{arr[]=;next}( in arr){=arr[]}{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
被使用,所以没有采取其他行动。在除第一个文件之外的所有文件中:如果 属性(第一个字段,</code>)是 <code>arr
键之一,则将值(第二个字段,</code>)设置为该值键,总是 <code>print
整行。
(在 gawk 4.2.1 中测试)
我有一个 属性 文件,其中包含数百行,如下所示 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
中的属性(字段 </code>)与主文件中的匹配时,它们的值应该被覆盖到主文件中。我尝试了以下代码但遗漏了一些重要的东西:</p>
<pre><code>awk -F= 'NR==FNR{val1=;val2=;next}{ if (==val1) printf " = "val2;else if ( != val1) print [=12=]}' changes.txt mainfile.txt
我看到它只将 change.txt
中的第二 属性 行注入到 mainfile.txt
中,而缺少第一行。所以,
- 如何添加所有
change.txt
行 - 上面的代码只是打印结果,并没有写入主文件,那我怎么能永久写入主文件呢?
我不太擅长 awk/shell 脚本编写,所以如果你能解释一下我在这里做错了什么,我将不胜感激
当输入文件中有多行时,您正在覆盖 val1
和 val2
的先前值。通常且非常常见的解决方案是将行读入关联数组。
awk -F= 'NR==FNR { a[] = [=10=]; next }
in a { print a[]; next } 1' changes.txt mainfile.txt >temp
mv temp mainfile.txt
当它看到该文件中的第一个字段时打印来自 changes.txt
的输入,否则打印原始输入行。结果被写入一个临时文件,然后我们将其重命名以将其移回原始 mainfile.txt
.
这里的-F =
是可疑的;也许把它拿出来,and/or 在检查它是否在 a
之前规范化 </code> 周围的空白。 Awk 中的字符串比较(或几乎所有 general-purpose 编程语言)将字符串视为不同,如果它们在文本周围有不同数量的空格。</p>
<p>最后一个 <code>1
是一个常见的 Awk shorthand,表示“如果你走到这一步,只需打印当前输入行。”
我会按照以下方式使用 GNU AWK
完成此任务
awk 'BEGIN{FS=OFS=" = "}NR==FNR{arr[]=;next}( in arr){=arr[]}{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
被使用,所以没有采取其他行动。在除第一个文件之外的所有文件中:如果 属性(第一个字段,</code>)是 <code>arr
键之一,则将值(第二个字段,</code>)设置为该值键,总是 <code>print
整行。
(在 gawk 4.2.1 中测试)