Linux / Bash如果条件等于包含单引号的字符串

时间:2017-03-11 02:32:02

标签: bash if-statement split

关于下面的命令,我尝试将空格分隔的日志文件内容插入到数组(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

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