(编辑:问题已解决,我在 Mac 上使用了 Windows 生成的文件,问题是行结尾。在 Studio 代码中打开文件并设置正确的行结尾为我解决了这个问题)
我有ProduKey
我想要处理的生成的文件awk
。
ProduKey 产生如下输出:
==================================================
Product Name : Microsoft Office Professional 2013
Product ID : 00000-00000-00000-00000
Product Key : 00000-00000-00000-00000-00000
Installation Folder : C:\Program Files\Microsoft Office\Office15\
Service Pack :
Build Number :
Computer Name : PC-000-0
Modified Time : 06.12.2018 14:03:44
==================================================
==================================================
Product Name : Windows 10 Pro
Product ID : 00000-00000-00000-00000
Product Key : 00000-00000-00000-00000-00000
Installation Folder : C:\Windows
Service Pack :
Build Number : 17763
Computer Name : PC-000-0
Modified Time : 18.07.2019 09:50:37
==================================================
我想从中生成 csv 文件,以便稍后将密钥、计算机名称和产品名称存储到数据库中。
所以可能的 csv 可能如下所示:
PC-000-0;Microsoft Office Professional 2013;00000-00000-00000-00000-00000
到目前为止我的方法:
BEGIN {
RS="\n\n";
FS="\n";
}
{
if ($1 ~ /Product Name/) {
split($1,productArray,":")
product = productArray[2]
}
if ($1 ~ /Product Key/) {
split($1,keyArray,":")
key = keyArray[2]
}
if ($1 ~ /Computer Name/ ) {
split($1,computerArray,":")
computer = computerArray[2]
#print product
#print key
#print computer
printf("\n")
printf("%s ; %s ; %s \n", computer, product, key)
}
}
我的问题是我无法连接字符串。或者也许当我想打印它们时字符串被覆盖?我花了几个小时在这上面,非常感谢您的帮助/提示。
如果有更优雅的方法来实现我的目标,请随时告诉我。
我在 Mac 上使用awk
(awk 版本 20070501),但我也有一个 Linux 盒子。
提前致谢。
答案1
您可以在这里使用 awk 的记录分隔符 ( RS
)。将其设置为==================================================
或={50}
是相同的东西,但作为正则表达式,可以让您将与单个产品关联的每组值视为单个“行”。如果您随后将输出字段分隔符 ( OFS
) 设置为;
并将输入字段分隔符 (FS
或-F
选项) 设置为\n
(换行符) 或:
,那么您可以执行类似这样的小技巧(使用 GNU awk):
$ awk RS='={50}' \
-v OFS=';' \
-F'[\n:]' \
'NR%2==0{print $16,$3,$7}' file
PC-000-0; Microsoft Office Professional 2013; 00000-00000-00000-00000-00000
PC-000-0; Windows 10 Pro; 00000-00000-00000-00000-00000
由于每个条目上面有一个=============================================
(50 =
) ,下面有一个,所以我们只想读取每一秒“行”。这就是NR%2==0
支票的作用。
那里有一些额外的空格,一个位于每个行的开头,另一个位于字段之间。如果它们有问题,您可以使用以下方法删除它们sed
:
$ awk -v RS='={50}' \
-v OFS=';' \
-F '[\n:]' \
'NR%2==0{print $16,$3,$7}' file |
sed -e 's/^ //' -e 's/; /;/g'
PC-000-0;Microsoft Office Professional 2013;00000-00000-00000-00000-00000
PC-000-0;Windows 10 Pro;00000-00000-00000-00000-00000
使用正则表达式是RS
GNU 扩展,因此可能不适用于您的 macOS。如果没有,请尝试以下操作:
$ awk -v RS='=' \
-v OFS=';' \
-F'[\n:]' \
'NR%50==1 && $2{print $16,$3,$7}' file |
sed -e 's/^ //' -e 's/; /;/g'
答案2
您可以尝试以下操作:
awk -F' : ' '/^Product Name/{pn=$2}
/^Product Key/{pk=$2}
/^Computer Name/{print $2,pn,pk}' OFS=\; file
字段分隔符FS
设置为:
以便通过 获取字段值$2
。
输出字段分隔OFS
符设置为;
。
Computer Name
每次找到关键字时都会打印该字符串。
答案3
正确的方法是创建一个数组,用于存储标签名称到值映射(f[]
如下),然后在每个记录的末尾打印您想要的任何值,例如:
$ cat tst.awk
BEGIN { OFS=";" }
{
sub(/\r$/,"")
tag = val = $0
sub(/[[:space:]]*:.*/,"",tag)
sub(/[^:]+[[:space:]]*:[[:space:]]*/,"",val)
f[tag] = val
}
/^=/ && (cnt++)%2 {
print f["Computer Name"], f["Product Name"], f["Product Key"]
delete f
}
$ awk -f tst.awk file
PC-000-0;Microsoft Office Professional 2013;00000-00000-00000-00000-00000
PC-000-0;Windows 10 Pro;00000-00000-00000-00000-00000
如果您愿意,使用相同的方法也可以轻松将整个输入文件转换为 CSV:
$ cat tst.awk
BEGIN { OFS=";" }
!/^=/ {
sub(/\r$/,"")
tag = val = $0
sub(/[[:space:]]*:.*/,"",tag)
sub(/[^:]+[[:space:]]*:[[:space:]]*/,"",val)
if ( !seen[tag]++ ) {
tags[++numTags] = tag
}
f[tag] = val
}
/^=/ && (cnt++)%2 {
if ( !doneHdr++ ) {
for (tagNr=1; tagNr<=numTags; tagNr++) {
tag = tags[tagNr]
printf "\"%s\"%s", tag, (tagNr<numTags ? OFS : ORS)
}
}
for (tagNr=1; tagNr<=numTags; tagNr++) {
tag = tags[tagNr]
printf "\"%s\"%s", f[tag], (tagNr<numTags ? OFS : ORS)
}
delete f
}
$ awk -f tst.awk file
"Product Name";"Product ID";"Product Key";"Installation Folder";"Service Pack";"Build Number";"Computer Name";"Modified Time"
"Microsoft Office Professional 2013";"00000-00000-00000-00000";"00000-00000-00000-00000-00000";"C:\Program Files\Microsoft Office\Office15\";"";"";"PC-000-0";"06.12.2018 14:03:44"
"Windows 10 Pro";"00000-00000-00000-00000";"00000-00000-00000-00000-00000";"C:\Windows";"";"17763";"PC-000-0";"18.07.2019 09:50:37";""
更改OFS=";"
为OFS=","
,输出将是一个文件,您可以在 Windows 中双击以使其在 Excel 中正确显示。