简体   繁体   中英

piping sed | awk or awk | sed

I can definitely be considered a sed/awk newbie. I have been working to do a multi-step filter without success. Each segment yields results when run on it's own, but when I chain them together I get nothing. I've tried sed|awk, awk|sed, sed|sed, awk|awk. They all fail so I'm assuming it's something well known by everyone but me.

The data is multi-line blocks of text, where each block can be treated as a record (hence the ">" delimiter). After we filter to just the ADV_NONCONN blocks, I'd like to then filter down the block of text to only the lines containing "bdaddr" or "RSSI". As far as I know, I'd need to pipe into a separate operation to do so.

sudo hcidump | awk 'BEGIN {RS=">"} /ADV_NONCONN/' | sed -n -e "/bdaddr/p" -e "/RSSI/p" > log.txt

hcidump output sample (one "record"):

HCI Event: LE Meta Event (0x3e) plen 43
    LE Advertising Report
      ADV_NONCONN_IND - Non connectable undirected advertising (3)
      bdaddr 0C:F3:EE:0D:70:89 (Public)
      Flags: 0x06
      Unknown type 0xff with 26 bytes data
      RSSI: -62

Running the inverse (the sed portion first, then awk) gives same empty set results. What simple thing have I missed?

There's no need to pipe awk to sed . Just add additional conditions in the awk command:

sudo hcidump | awk -v RS=">" '/ADV_NONCONN/ {
    n = split($0, line, /\n/);
    for (i = 1; i <= n; i++) {
        if (line[i] ~ /bdaddr|RSSI/) print line[i];
    }
}' > log.txt

OK, so I eventually figured it out. I believe that the awk output is not eminently pipe-able because of some sort of buffering/not closing that it is doing with the input stream. Since the original question, I've added the timestamp from the hcidump.

So, first I prepend a unique character (@) before the timestamp with sed, then pipe that to awk, which treats the multiple lines as a single record using that unique character (@) as the record delimiter, filters to the records I want (ADV_NONCONN) then assembles the appropriate output from the fields it reads (which now includes the timestamp at the head of the record).

sudo hcidump -t | sed -n '/HCI Event/{s/^/@/};p' | awk 'BEGIN {RS="@"} {-F '[\n]'} /ADV_NONCONN/ {print $1 " " $2 ", " $23 ", " $35}' > a.txt

The solution to the original question would be:

sudo hcidump | awk 'BEGIN {RS=">"} {-F '[\n]'} /ADV_NONCONN/ {print $20 ", " $32}' > a.txt

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