Bash sed匹配行并在文本文件中返回其他行

时间:2018-10-03 13:01:34

标签: bash awk sed grep

我正在尝试获取基于HFP的电话应用程序的对象路径。我们有一个名为list-modems的脚本,它能够列出对象路径的属性。我想返回具有Powered = b'1'行的对象路径,但是不确定该行将在哪里,我认为可以用sed和regex来完成,但是我对此没有丰富的经验。因此,我需要一些帮助。有问题的文件具有如下文本:

[ /hfp/org/bluez/hci0/dev_7C_46_85_3E_36_66 ]
    Interfaces = b''
    Lockdown = b'0'
    Online = b'0'
    Features = b''
    Type = b'hfp'
    Powered = b'0'
    Name = b'MCO'
    Emergency = b'0'
[ /hfp/org/bluez/hci0/dev_D0_FC_CC_12_6D_4D ]
    Interfaces = b'org.ofono.VoiceCallManager org.ofono.CallVolume org.ofono.Handsfree org.ofono.NetworkRegistration '
    Lockdown = b'0'
    Online = b'1'
    Serial = b'D0:FC:CC:12:6D:4D'
    Features = b'net '
    Type = b'hfp'
    Powered = b'1'
    Name = b"Ak\xc4\xb1n's J7 Prime"
    Emergency = b'0'
    [ org.ofono.VoiceCallManager ]
        EmergencyNumbers = b'08 000 999 110 112 911 118 119 '
    [ org.ofono.CallVolume ]
        Muted = b'0'
        SpeakerVolume = b'50'
        MicrophoneVolume = b'50'
    [ org.ofono.Handsfree ]
        DistractedDrivingReduction = b'0'
        Features = b'three-way-calling echo-canceling-and-noise-reduction voice-recognition release-all-held release-specified-active-call private-chat create-multiparty hf-indicators '
        EchoCancelingNoiseReduction = b'1'
        BatteryChargeLevel = b'3'
        InbandRinging = b'1'
        VoiceRecognition = b'0'
    [ org.ofono.NetworkRegistration ]
        Mode = b'auto-only'
        Status = b'registered'
        Strength = b'40'
        Name = b'vodafone TR'
[ /hfp/org/bluez/hci0/dev_D8_5B_2A_5B_7B_E6 ]
    Interfaces = b''
    Lockdown = b'0'
    Online = b'0'
    Features = b''
    Type = b'hfp'
    Powered = b'0'
    Name = b'Samsung Galaxy S7'
    Emergency = b'0'
[ /hfp/org/bluez/hci0/dev_14_5A_05_AB_66_F4 ]
    Interfaces = b''
    Lockdown = b'0'
    Online = b'0'
    Features = b''
    Type = b'hfp'
    Powered = b'0'
    Name = b"Ekrem iPhone'u"
    Emergency = b'0'
[ /phonesim ]
    Interfaces = b''
    Lockdown = b'0'
    Online = b'0'
    Features = b''
    Type = b'hardware'
    Powered = b'0'
    Emergency = b'0'

我想做的就是返回对象路径,即/hfp/org/bluez/hci0/dev_D0_FC_CC_12_6D_4D,如果它具有属性Powered = b'1'。请记住,此文件是随机生成的,即,每个属性的位置在一次运行之间会有所不同。

到目前为止,我具有以下正则表达式以匹配对象路径:

./list-modems | grep -E '/hfp/org/bluez/hci[0-9]/dev_[0-9A-F]{2}_[0-9A-F]{2}_[0-9A-F]{2}_[0-9A-F]{2}_[0-9A-F]{2}_[0-9A-F]{2}'

非常感谢您提供任何帮助,以进一步解决此问题。预先感谢

编辑: 此示例的预期输出(因为它具有Powered = b'1'):

/hfp/org/bluez/hci0/dev_D0_FC_CC_12_6D_4D

2 个答案:

答案 0 :(得分:2)

您可以在此处使用awk:

UML

如果行以 awk '/^\[/{op=$0;next} /Powered.*b.1./{print op;exit}' ./list-modems 开头,则它将行捕获到变量[中。如果一行与op相匹配,那么它将打印该变量中的内容并退出(假设文件中只有一个匹配项。如果期望更多匹配,则只需删除/Powered.*b.1./)。

您也可以使用自己的;exit正则表达式来匹配路径,但是考虑到您的文件格式,我认为这太过分了。

您也可以通过在打印时通过gensub杀死这些多余的括号:

/^\[/

对样本数据采取行动:

 awk '/^\[/{op=$0;next} /Powered.*b.1./{print gensub(/\[\s|\s\]/,"","g", op);exit}' ./list-modems

答案 1 :(得分:0)

使用grep和tr

./list-modems | grep -zPo '/hfp/org/bluez/hci\d/dev(_[0-9A-F]{2}){6}(?=((?!/hfp/org/bluez/hci)[\s\S])*Powered = b\0471\047)' | tr '\0' '\n'

并转移递归正则表达式

./list-modems | grep -zPo '(/hfp/org/bluez/hci\d/dev(_[0-9A-F]{2}){6})(?=((?!(?1))[\s\S])*Powered = b\0471\047)' | tr '\0' '\n'