-2

I have a log file containing multiple IDs like this:

INFO: [Synth 8-3491] module 'IOBUF' declared at 'C:/Xilinx/Vivado/2017.3/scripts/rt/data/unisim_comp.v:22655' bound to instance 'LED_tri_iobuf_7' of component 'IOBUF' [C:/.../block_design_wrapper.vhd:342]
INFO: [Synth 8-3491] module 'IOBUF' declared at 'C:/Xilinx/Vivado/2017.3/scripts/rt/data/unisim_comp.v:22655' bound to instance 'MAX11603_I2C_scl_iobuf' of component 'IOBUF' [C:/.../block_design_wrapper.vhd:349]
INFO: [Synth 8-3491] module 'IOBUF' declared at 'C:/Xilinx/Vivado/2017.3/scripts/rt/data/unisim_comp.v:22655' bound to instance 'MAX11603_I2C_sda_iobuf' of component 'IOBUF' [C:/.../block_design_wrapper.vhd:356]
INFO: [Synth 8-3491] module 'block_design' declared at 'C:/Projects/.../block_design.vhd:2346' bound to instance 'block_design_i' of component 'block_design' [C:/.../block_design_wrapper.vhd:363]
---------------------------------------------------------------------------------
Starting RTL Elaboration : Time (s): cpu = 00:00:07 ; elapsed = 00:00:07 . Memory (MB): peak = 491.250 ; gain = 104.844
---------------------------------------------------------------------------------
INFO: [Synth 8-638] synthesizing module 'block_design' [C:/Projects/.../block_design.vhd:2469]
INFO: [Synth 8-638] synthesizing module 'block_design_axi_mem_intercon_0' [C:/Projects/.../block_design.vhd:1403]
INFO: [Synth 8-638] synthesizing module 'm00_couplers_imp_1Y96WCF' [C:/Projects/.../block_design.vhd:81]
INFO: [Synth 8-3491] module 'block_design_auto_pc_0' declared at 'C:/.../block_design_auto_pc_0_stub.vhdl:5' bound to instance 'auto_pc' of component 'block_design_auto_pc_0' [C:/Projects/.../block_design.vhd:267]
INFO: [Synth 8-638] synthesizing module 'block_design_auto_pc_0' [C:/.../block_design_auto_pc_0_stub.vhdl:71]
INFO: [Synth 8-256] done synthesizing module 'm00_couplers_imp_1Y96WCF' (2#1) [C:/Projects/.../block_design.vhd:81]
INFO: [Synth 8-638] synthesizing module 'm01_couplers_imp_1SYGEF3' [C:/Projects/.../block_design.vhd:422]
INFO: [Synth 8-256] done synthesizing module 'm01_couplers_imp_1SYGEF3' (3#1) [C:/Projects/.../block_design.vhd:422]
INFO: [Synth 8-638] synthesizing module 'm02_couplers_imp_1MNJOVZ' [C:/Projects/.../block_design.vhd:611]

Each INFO line contains a message from a specific tool (here Synth) and an ID xx-yyyy.

How can I extract all occuring IDs in a log file using Bash and tools available in Git-Bash? At the end, I need to split the input log file into multiple files, containing only messages belonging to the same ID. So the list of IDs must be unique.

I did the same scripting already in PowerShell. This approach uses regular expression matching and an array of IDs that's extended for every new ID.

It processes a log file in 3 steps:

  1. split a log file by category
  2. collect a unique list of message IDs
  3. split each categorized log file into separate files per message ID

The main question is: How to create this list of unique message IDs? (step 2)


PowerShell Script:

[CmdletBinding()]
Param(
  [Parameter(Mandatory=$True,Position=1)]
  [string]$ReportFile
)

$SynthesisLogFile = Get-Item $ReportFile
$SynthesisLog = $SynthesisLogFile.BaseName

$Categories = @("INFO", "CRITICAL WARNING", "WARNING", "ERROR")

foreach ($Cat in $Categories)
{ Write-Host "Extracting category $Cat from $ReportFile ..."
  $line=0
  cat ".\$ReportFile" | %{ $line=$line+1; if ($_ -match "^$Cat") { "$line`t$_"} } > ".\$SynthesisLog.$Cat.log"

  $IDs = @();
  cat ".\$SynthesisLog.$Cat.log" | %{ $m = $_ -match "^\d+\t$($Cat): \[(\w+) (\d+-\d+)\]"; $mm = $Matches[2]; if ($IDs -notcontains $mm) {$IDs = $IDs + $mm } }
  foreach ($ID in $IDs)
  { Write-Host "  Extracting ID: $ID ..."
    cat ".\$SynthesisLog.$Cat.log" | Select-String "$ID" > ".\$SynthesisLog.$Cat.$ID.log"
  }
}

Here is my current Bash script:

#! /bin/bash

LOGFILE=$(basename "$1")
PREFIX="${LOGFILE%.*}"

for CATEGORY in INFO WARNING "CRITICAL WARNING" ERROR; do
  CATEGORY_FILE="$PREFIX.$CATEGORY.log"
  echo "Extracting category '$CATEGORY' from '$LOGFILE' ..."
  grep -n "^$CATEGORY: " "$1" > "$CATEGORY_FILE"

  if [[ -s $CATEGORY_FILE ]]; then
    echo "  File contains data"
  else
    echo "  Deleting empty output file for category '$CATEGORY'"
    rm "$CATEGORY_FILE"
  fi
done

Here is my final Bash script improved by the answer below:

#! /bin/bash

LOGFILE=$(basename "$1")
PREFIX="${LOGFILE%.*}"

for CATEGORY in INFO WARNING "CRITICAL WARNING" ERROR; do
  CATEGORY_FILE="$PREFIX.$CATEGORY.log"
  echo "Extracting category '$CATEGORY' from '$LOGFILE' ..."
  grep -n "^$CATEGORY: " "$1" > "$CATEGORY_FILE"

  if [[ -s $CATEGORY_FILE ]]; then
    for ID in $(grep -P "^\d+:$CATEGORY: \[\w+ \d+-\d+\]" "$CATEGORY_FILE" | awk -F' ' '{print $3}' | tr -d ']' | sort | uniq); do
      ID_FILE="$PREFIX.$CATEGORY.$ID.log"
      echo "  Extracting ID: $ID ..."
      grep "$ID" "$CATEGORY_FILE" > "$ID_FILE"
    done
  else
    echo "  Deleting empty output file for category '$CATEGORY'"
    rm "$CATEGORY_FILE"
  fi
done
Paebbels
  • 15,573
  • 13
  • 70
  • 139
  • I don't think the answer should be in the question. – Greg Schmit Mar 04 '18 at 18:44
  • @GregSchmit The real answer is in the answer marked as solution. But people might be interested in seeing the assembled solution. I added it to my question, because self-answering is not so welcome at SO. – Paebbels Mar 04 '18 at 18:47
  • I think you should answer your own question but keep the current "accepted" if yours is derivative, since it's the one you used. I've never seen anything negative about answering your own question, and if someone gives you crap about it, tell them to ask the mods in meta to disallow self-answers. As they are currently allowed, that's where answers should go. Just my 2 cents. – Greg Schmit Mar 04 '18 at 18:50

1 Answers1

1

Try this ...

$ cat file.sh 
INFO: [Synth 8-3491] module 'IOBUF' declared at 'C:/Xilinx/Vivado/2017.3/scripts/rt/data/unisim_comp.v:22655' bound to instance 'MAX11603_I2C_sda_iobuf' of component 'IOBUF' [C:/.../block_design_wrapper.vhd:356]
INFO: [Synth 8-3491] module 'block_design' declared at 'C:/Projects/.../block_design.vhd:2346' bound to instance 'block_design_i' of component 'block_design' [C:/.../block_design_wrapper.vhd:363]
---------------------------------------------------------------------------------
Starting RTL Elaboration : Time (s): cpu = 00:00:07 ; elapsed = 00:00:07 . Memory (MB): peak = 491.250 ; gain = 104.844
---------------------------------------------------------------------------------
INFO: [Synth 8-638] synthesizing module 'block_design' [C:/Projects/.../block_design.vhd:2469]
INFO: [Synth 8-638] synthesizing module 'block_design_axi_mem_intercon_0' [C:/Projects/.../block_design.vhd:1403]
INFO: [Synth 8-638] synthesizing module 'm00_couplers_imp_1Y96WCF' [C:/Projects/.../block_design.vhd:81]
INFO: [Synth 8-3491] module 'block_design_auto_pc_0' declared at 'C:/.../block_design_auto_pc_0_stub.vhdl:5' bound to instance 'auto_pc' of component 'block_design_auto_pc_0' [C:/Projects/.../block_design.vhd:267]
INFO: [Synth 8-638] synthesizing module 'block_design_auto_pc_0' [C:/.../block_design_auto_pc_0_stub.vhdl:71]
INFO: [Synth 8-256] done synthesizing module 'm00_couplers_imp_1Y96WCF' (2#1) [C:/Projects/.../block_design.vhd:81]


$ cat file.sh | grep -P "^\d+:INFO: \[\w+ \d+-\d+\]" | awk -F' ' '{print $3}' | tr -d ']' | sort | uniq
8-256
8-3491
8-638
Paebbels
  • 15,573
  • 13
  • 70
  • 139
hch
  • 162
  • 5
  • I improved your grep pattern to exclude some false positives. The final script version is now inserted in my original question using your command chain. Thanks. – Paebbels Mar 04 '18 at 18:43