我正在做一个项目,需要修正几千行数据。我已经完成了一半的工作,现在还停留在最后一部分。
我有一个名为 tree.txt 的文件,其中包含所有节点的列表,但是由于某些错误或其他原因,许多节点的标签名称不正确。tree.txt-
Main_Overview/Ballast/BA-02:Tag=BA-02
Main_Overview/Ballast/BA-03:Tag=BA-02-1
Main_Overview/Ballast/BA-04:Tag=BA-02-2
如上所示,节点 BA-03 和 BA-04 的标签名称不正确,因此使用 CI 中的文件处理能够更正此文本文件,并在文件中打印相应节点的所有不正确标签,如下所示。incorrect_tags.txt-
"BA-02-1" "BA-03"
"BA-02-2" "BA-04"
现在最后的事情是,有很多其他文件使用了错误的标签名称,我需要用正确的标签替换所有错误的标签。
我解决这个问题的方法是 ->
- 我将有两个变量节点和标签,这两个变量将从上面获取数据不正确的标签.txt。我将在每个文件中搜索标签的值并将其替换为相应节点的值。
- 一旦我在所有文件中完成搜索和替换第一个标签,它将对剩余的文件执行相同的操作。
但是由于我的知识有限,我不知道这是否可行。此外,即使我得到一些语法方面的帮助,我也能做其他的事情。谢谢
编辑-
我需要搜索和替换数据的其他文件有所不同..例如 Ballast.j1
:1176:489:15:30:CompID=118680:Text=BA-02:uiFont=Arial-PLAIN-10:
:1269:489:15:30:CompID=118681:Text=BA-02-1:uiFont=Arial-PLAIN-10:
:1013:489:15:30:CompID=118677:Text=BA-02-2:uiFont=Arial-PLAIN-10:
有近 2000 个 .j1 文件,我将在所有这些 .j1 文件中搜索每个标签名称,并将其替换为正确的标签名称或节点。
答案1
您只是在寻找这个吗?
sed -i '\%/\([^/:]*\):Tag=\1%n;s%%/\(\([^/:]*\):Tag=\)[^/:-]*-[^/:-]*%\1\2%' *.j1
(尝试不使用-i
来查看输出而不将其写回原始文件 - 管道到less
以便您可以暂停和来回滚动。)
第一个表达式中的括号用于查找斜杠和冒号之间的字符串;如果我们发现该字符串后面紧跟着与Tag=
括号中匹配的字符串相同的字符串,则表示成功。反斜杠括号捕获了此字符串,因此我们可以将其引用为\1
。
如果我们没有找到这个模式,后面的字符串Tag=
一定与捕获的字符串不同;如果是这样,Tag=
用捕获的字符串替换后面的字符串。正则表达式替换包含单个破折号且不包含破折号、冒号或斜线的序列(因此,直到第二个破折号之前,或者第一个斜线或冒号之前)。
如果您使用的是 *BSD (包括 Mac OS),那么您所需要的-i ''
不仅仅是-i
。
另一种方法是,你可以将映射重构为sed
脚本。如果你有一个incorrect_tags.txt
类似
"BA-02-1" "BA-03"
"BA-02-2" "BA-04"
然后你可以运行以下脚本
sed 's%^"%s/%;s%" "%/%;s%"$%/g%' incorrect_tags.txt
生成...另一个sed
脚本现在看起来像
s/BA-02-1/BA-03/g
s/BA-02-2/BA-04/g
您可以将其传递给另一个实例来sed
修改包含要替换的这些标记的文件。
完整的流程如下
sed 's%^"%s/%;s%" "%/%;s%"$%/g%' incorrect_tags.txt |
sed -i -f - *.j1
再次,您可能想先尝试一下,-i
看看输出是什么样子的。此外,您sed
可能不喜欢该-f
选项,或者可能不支持在标准输入上读取脚本;也许只需将第一次sed
调用的输出保存到临时文件中,然后将临时文件名作为文件名参数传递给-f
。
请注意,这将要求标签不重叠 - 如果您先用 B 替换 A,然后用 C 替换 B,最终结果将与您指定“A”“C”一样。一种解决方法是切换顺序,以便先用 C 替换 B,然后再用 B 替换 A。