【问题标题】:How do I define a list of strings and replace each instance of the string in files in a subdirectory?如何定义字符串列表并替换子目录中文件中字符串的每个实例?
【发布时间】:2020-03-09 06:31:09
【问题描述】:

输入

假设我在 /directory/ 子目录中有三个文件:a.txtb.txtc.txt

a.txt
var1=bla
var2=blabla
var3=blablabla

b.txt
foo1=bar
foo2=barbar
foo3=barbarbar

c.txt
name1=string
name2=string2
name3=string3

我创建了第 4 个文件,variables.txt

variables.txt
var2=new
foo1=newnew
foo3=newnewnew

想要的输出

我想要一个 bash 脚本,它使用 variables.txt 的内容来编辑 /directory/ 中的所有文件,用 variables.txt 中的匹配变量替换任何文件.例如,a.txtb.txtc.txt 变为:

a.txt
var1=bla
var2=new
var3=blablabla

b.txt
foo1=newnew
foo2=barbar
foo3=newnewnew

c.txt
name1=string
name2=string2
name3=string3

c.txt 不会改变,因为 variable.txt 中没有任何内容与其变量匹配。

这个脚本会是什么样子?

上下文

实际上,我有大约 20 个文件,每个文件有 5-20 个变量,我需要更改每个文件中的 3-4 个变量。其他用户也会使用 variables.txt,定义它以适合他们的目的,所以我可以将 variables.txt 写得越简洁越好。幸运的是,每个变量都有一个唯一的名称,并且只在该子目录的文件中出现一次。谢谢!

【问题讨论】:

  • @oguzismail 感谢您的回复。我很乐意自己尝试更多,但问题是我什至不知道如何开始。例如,构建一个 sed 查询:我可以做类似 while read variables.txt;执行 sed -i ...,但我需要循环读取两个字符串:一个字符串定义我将搜索的模式,第二个字符串定义我将替换模式的内容。我不确定如何构建它。

标签: bash


【解决方案1】:

使用 awk 和 inplace 扩展:

awk -F= --include inplace '
  NR==FNR{a[$1]=$2;next}
  ($1 in a){$2=a[$1]}
  1' variable.txt /directory/[abc].txt

此脚本用文件variable.txt 的内容填充数组a

对于其他文件,如果参数是数组的一部分,它会替换值。

--include inplace 选项允许直接更改文件(无需创建临时文件),这与sed -i 选项相同。

【讨论】:

  • 这行得通,谢谢!我不得不解决 --include inplace 因为我的 Linux 发行版是 centos 7,它似乎不支持 awk 4.1。我的最终代码是(抱歉不知道如何在 cmets 中进行代码降价): ````for i in /directory/*.txt;执行 awk -F= ' BEGIN{OFS="=";}NR==FNR{a[$1]=$2;next} ($1 in a){$2=a[$1]} 1' variables.txt $i > tmp && mv tmp $i 完成 ````
  • 更正:($1 in a && $1>0) 否则它会将 OFS 添加到空行,因为它还将 variables.txt 中的空行存储在数组中。
猜你喜欢
  • 1970-01-01
  • 2016-03-24
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
  • 2019-05-21
  • 1970-01-01
  • 2017-06-22
相关资源
最近更新 更多