简体   繁体   中英

Bash sed match line and return other line in a text file

I am trying to get object path for HFP-based telephony application. We have a script called list-modems which is able to list properties of object paths. I want to return the object path that has the Powered = b'1' line, but it is not certain where this line will be, I think this might be done with sed and regex, but I have no substantial experience with it. Therefore, I need some help. The file in question has some text like the following:

[ /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'

What I want to do is I want to return the object path ie /hfp/org/bluez/hci0/dev_D0_FC_CC_12_6D_4D if it has the property Powered = b'1' . Keep in mind that this file is randomly generated, ie places of each properties differ from one run to another run.

So far I have the following regex to match the object path:

./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}'

Any help is greately appreciated how to further tackle this issue. Thanks in advance

EDIT: Expected output for this example (since it has Powered = b'1' ):

/hfp/org/bluez/hci0/dev_D0_FC_CC_12_6D_4D

You could use awk here:

 awk '/^\[/{op=$0;next} /Powered.*b.1./{print op;exit}' ./list-modems

If the line starts with a [ then it grabs the line into variable op . If a line matches /Powered.*b.1./ then it prints whatever is in that variable and exits (assuming only one match in the file. If more matches are expected then just remove the ;exit ).

You could also sub out the /^\\[/ regex with your own to match the path, but given your file format I think that's overkill.

You can kill off those extra brackets too by running it through gensub as you print:

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

In action on your sample data:

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

using grep and 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'

and diverting recursive regex

./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'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM