[英]Match strings from two files and append line with matching string from first file to end of line of second file
So this is a bit tricky and I'm having a heck of a time trying to figure it out. 因此,这有点棘手,我花了一些时间试图弄清楚。
I have two different files, one is in rackdiag format like so: 我有两个不同的文件,一个是rackdiag格式的,如下所示:
#file1
rackdiag {
rack {
42U;
description = "1.1.1";
1: "serverone" [4U];
5: servertwo [2U];
7: serverthree\nblah [3U];
}
rack {
42U;
description = "1.1.2";
1: servertwoone [4U];
5: "servertwotwo" [2U];
}
}
Etc. 等等。
And the other is a list of server names like so: 另一个是服务器名称列表,如下所示:
#file2
serverone.domain.com
servertwo.domain.com
serverthree.domain.com
I'm trying to match strings between the two files and insert the line with the matching string from the first file onto the end of the second file with a couple additions. 我正在尝试在两个文件之间匹配字符串,并将带有匹配字符串的行从第一个文件插入到第二个文件的末尾,并添加了一些附加内容。 I want it to end up like this in the second file: 我希望它像这样在第二个文件中结束:
serverone.domain.com #1.1.1 1: "serverone" [4U];
servertwo.domain.com #1.1.1 5: servertwo [2U];
servertwoone.domain.com #1.1.2 1: servertwoone [4U];
I managed to get this far: 我设法做到了这一点:
#!/bin/bash
cat serverlist.txt | while read line;
do
#grep for matching strings and output entire line when match found to $line2 variable
line2=$(grep -w "$line" row01.txt)
echo "$line "#" $line2"
done > halp.txt
exit
Which outputs this: 输出以下内容:
servertwo.domain.com #5: servertwo.domain.com [2U];
But I noticed that it's missing some that should match for some reason. 但是我注意到由于某种原因,它缺少一些应该匹配的东西。
Like, in the actual file I have this line 就像,在实际文件中我有这行
33: servername [2U];
And this line in the second file: 第二行中的这一行:
servername.blahhosting.com
When I tried running the script the output was only: 当我尝试运行脚本时,输出仅为:
servername.blahhosting.com #
Would anybody be able to help me both getting the 1.1.1/1.1.2 etc. to appear in the output and to figure out why it might be missing some of the lines that match? 有人能帮助我让1.1.1 / 1.1.2等出现在输出中并弄清楚为什么它可能缺少某些匹配的行吗?
Thank you very much! 非常感谢你!
Edit 1: 编辑1:
rackdiag {
rack {
42U;
description = "5.1.1";
1: servertwoone [4U];
1: "servertwoone" [4U];
1: servertwoone\nserveronetwo [4U];
1: "servertwoone\nserveronetwo" [4U];
1: servertwo-1\nserverone1 [4U];
1: "servertwo-2\nserverone2" [4U];
1: servertwoone-1 [4U];
1: servertwoone-2 [4U];
1: servertwoone1 [4U];
1: servertwoone2 [4U];
1: servertwoone;
}
rack {
42U;
description = "5.1.2";
1: server two one [4U];
1: servertwoone [4U];
1: server.two.one [4U];
}
}
If there is no [2U] etc. and it's blank at the end, that means it's [1U] 如果没有[2U]等,并且末尾为空白,则表示为[1U]
In the case of names with \\n, that means that the server has more than one label on the physical case. 对于带有\\ n的名称,这意味着服务器在物理外壳上具有多个标签。 I think thats it 我认为就是这样
Your question isn't clear but here's the right approach and a start towards solving your problem: 您的问题尚不清楚,但这是正确的方法,也是解决您的问题的起点:
$ cat tst.awk
NR==FNR {
if ( $1 == "description" ) {
desc = $NF
gsub(/^"|";$/,"",desc)
}
else if ( $1 ~ /^[0-9]+:/ ) {
nmbr = $1
sub(/^[[:space:]]*[^[:space:]]+[[:space:]]+/,"")
if ( $NF ~ /\[.*\];$/ ) {
blob = $NF
sub(/[^[:space:]]+$/,"")
}
else {
blob = "[1U];"
}
sub(/[[:space:]]+$/,"")
numSrvrs = split($0,srvrs,/\\n/)
for (srvrNr=1; srvrNr<=numSrvrs; srvrNr++) {
srvr = srvrs[srvrNr]
gsub(/^"|"$/,"",srvr)
srvr2data[srvr] = "#" desc " " nmbr " " $0 " " blob
printf "TRACE: srvr2data[%s] = <%s>\n", srvr, srvr2data[srvr]
}
}
next
}
{
srvr = $0
sub(/\..*/,"",srvr)
print $0, srvr2data[srvr]
}
When run against your first 2 sample input files: 针对前两个样本输入文件运行时:
$ awk -f tst.awk file1 file2
TRACE: srvr2data[serverone] = <#1.1.1 1: "serverone" [4U];>
TRACE: srvr2data[servertwo] = <#1.1.1 5: servertwo [2U];>
TRACE: srvr2data[serverthree] = <#1.1.1 7: serverthree\nblah [3U];>
TRACE: srvr2data[blah] = <#1.1.1 7: serverthree\nblah [3U];>
TRACE: srvr2data[servertwoone] = <#1.1.2 1: servertwoone [4U];>
TRACE: srvr2data[servertwotwo] = <#1.1.2 5: "servertwotwo" [2U];>
serverone.domain.com #1.1.1 1: "serverone" [4U];
servertwo.domain.com #1.1.1 5: servertwo [2U];
serverthree.domain.com #1.1.1 7: serverthree\nblah [3U];
When run using your 3rd input file ( Edit 1
in your question) and no associated "file2" (since you didn't provide one) so all you get is the trace output as the data from the first file is being populated: 当使用第三个输入文件(问题中的Edit 1
)运行并且没有关联的“ file2”(因为您没有提供文件)时,因此,您得到的只是跟踪输出,因为正在填充第一个文件中的数据:
$ awk -f tst.awk file3 /dev/null
TRACE: srvr2data[servertwoone] = <#5.1.1 1: servertwoone [4U];>
TRACE: srvr2data[servertwoone] = <#5.1.1 1: "servertwoone" [4U];>
TRACE: srvr2data[servertwoone] = <#5.1.1 1: servertwoone\nserveronetwo [4U];>
TRACE: srvr2data[serveronetwo] = <#5.1.1 1: servertwoone\nserveronetwo [4U];>
TRACE: srvr2data[servertwoone] = <#5.1.1 1: "servertwoone\nserveronetwo" [4U];>
TRACE: srvr2data[serveronetwo] = <#5.1.1 1: "servertwoone\nserveronetwo" [4U];>
TRACE: srvr2data[servertwo-1] = <#5.1.1 1: servertwo-1\nserverone1 [4U];>
TRACE: srvr2data[serverone1] = <#5.1.1 1: servertwo-1\nserverone1 [4U];>
TRACE: srvr2data[servertwo-2] = <#5.1.1 1: "servertwo-2\nserverone2" [4U];>
TRACE: srvr2data[serverone2] = <#5.1.1 1: "servertwo-2\nserverone2" [4U];>
TRACE: srvr2data[servertwoone-1] = <#5.1.1 1: servertwoone-1 [4U];>
TRACE: srvr2data[servertwoone-2] = <#5.1.1 1: servertwoone-2 [4U];>
TRACE: srvr2data[servertwoone1] = <#5.1.1 1: servertwoone1 [4U];>
TRACE: srvr2data[servertwoone2] = <#5.1.1 1: servertwoone2 [4U];>
TRACE: srvr2data[servertwoone;] = <#5.1.1 1: servertwoone; [1U];>
TRACE: srvr2data[server two one] = <#5.1.2 1: server two one [4U];>
TRACE: srvr2data[servertwoone] = <#5.1.2 1: servertwoone [4U];>
TRACE: srvr2data[server.two.one] = <#5.1.2 1: server.two.one [4U];>
You didn't tell us what that "[4U]" field is so I named it blob
- obviously change it to whatever it is. 您没有告诉我们“ [4U]”字段是什么,所以我将其命名为blob
显然将其更改为任何内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.