关于下面的命令,我尝试将空格分隔的日志文件内容插入到数组(arr)中,然后创建一个条件来查找并从中提取特定的字符串。 问题是主题字符串被单引号包围,我不知道在条件语句中涉及这些引用的正确语法是什么:
cat file.log | nawk '{split($0,arr," "); for (i=1;i<=NF;i++) if (arr[i]=='serviceid') printf ("%s,%s\n",arr[i],arr[i+1])}'
我试过这些:
cat file.log | nawk '{split($0,arr," "); for (i=1;i<=NF;i++) if (arr[i]=="'serviceid'") printf ("%s,%s\n",arr[i],arr[i+1])}'
cat file.log | nawk '{split($0,arr," "); for (i=1;i<=NF;i++) if (arr[i]=="\'serviceid\'") printf ("%s,%s\n",arr[i],arr[i+1])}'
我还试图基于单引号进行拆分,例如split($0,arr,/\'/)
,但它也失败了。
这是日志的一部分:'serviceid': 1002,
是我要尝试导航的部分。当我执行print arr[301]
时,它会返回'serviceid':
。但是当我命令(i = 1; i&lt; = NF; i ++)if(arr [i] =='serviceid',){print $ i}时,我会在单引号周围出现语法错误。
'originTransactionID': '00720170311', 'serviceFeeExpiryDate': datetime.datetime(2019, 12, 23, 12, 0, tzinfo=), 'accountFlagsBefore': {'activationStatusFlag': True, 'supervisionPeriodExpiryFlag': False, 'supervisionPeriodWarningActiveFlag': False, 'negativeBarringStatusFlag': False, 'serviceFeePeriodExpiryFlag': False, 'serviceFeePeriodWarningActiveFlag': False}, 'serviceid': 1002, 'supervisionExpiryDate': datetime.datetime(2019, 12, 23, 12, 0, tzinfo=), 'dedicatedAccountInformation': [{'startDate': datetime.datetime(9999, 12, 31, 0, 0, tzinfo=), 'dedicatedAccountValue1': '0', 'dedicatedAccountID': 1
答案 0 :(得分:2)
只需使用包含所需值的变量:
awk -v str="'serviceid'" … …
这将避免在脚本内部进行复杂引用 整个awk脚本在单引号内,这使单引号的使用变得困难。
此外,您发布的日志文件示例包含一个结尾冒号'serviceid':
的字段。如果字段在空白区域分割。
您可以将其附加到上面定义的变量或使用~
(匹配)运算符而不是==
(相等)运算符。该运算符(~
)将匹配包含'serviceid'
的任何字段。
像这样:
nawk -vstr="'serviceid'" '
$0~str{
split($0,arr," ");
for (i=1;i<=NF;i++)
if (arr[i]~str)
printf ("%s,%s\n",arr[i],arr[i+1])
}' file.log
请注意,不需要猫,因为awk(在这种情况下为nawk)完全能够读取文件。
另外,我添加了$0~str
仅处理包含此类文本的行。
在一行中:
nawk -vstr="'serviceid'" '$0~str{ split($0,arr," "); for (i=1;i<=NF;i++) if (arr[i]~str) printf ("%s,%s\n",arr[i],arr[i+1]) }' infile