MajorasKid
MajorasKid

Reputation: 873

Split terminal output while keeping spaces

I'm trying to split the output of a program on a fixed position. I found the recommendation of awk, but I need to keep the empty spaces in the last part of the output. This is what I need to do:

The output I'm trying to split looks like this:

  trace-cmd-16029 [000]  5635.254957: function:             switch_mm_irqs_off
  trace-cmd-16029 [000]  5635.254961: function:                load_new_mm_cr3
  trinity-c0-16027 [000]  5635.254961: function:             finish_task_switch
  trinity-c0-16027 [000]  5635.254963: function:             smp_reschedule_interrupt
  trinity-c0-16027 [000]  5635.254965: function:             scheduler_ipi
  trinity-c0-16027 [000]  5635.254965: function:                irq_enter
  trinity-c0-16027 [000]  5635.254965: function:                   rcu_irq_enter
  trinity-c0-16027 [000]  5635.254965: function:                   rcu_nmi_enter
  trinity-c0-16027 [000]  5635.254965: function:                sched_ttwu_pending

I need it to be formatted like this:

load_new_mm_cr3
finish_task_switch
smp_reschedule_interrupt
scheduler_ipi
   irq_enter
      rcu_irq_enter
      rcu_nmi_enter
   sched_ttwu_pending

Basically the preamble always ends with "function:", followed by a lot of empty spaces. Some empty spaces are not from formatting but show called subfunctions (e.g. the empty space infront of "load_nw_mm_cr3" is there because its a subfunction of "switch_mm_irqs_off"). AWK will remove all empty spaces even the ones I still need.

Anybody with some tips how I can format this output in the terminal?

Upvotes: 0

Views: 105

Answers (2)

RavinderSingh13
RavinderSingh13

Reputation: 133428

If you don't want to hardcode number of spaces and number of spaces can be dynamic then try following.

awk '
FNR==NR{
  sub(/.*function:/,"")
  match($0,/[[:space:]]+/)
  val=substr($0,RSTART,RLENGTH)
  num=gsub(/ /,"&",val)
  a[FNR]=num
  min=min<num?min?min:num:num
  next
}
{
  if(a[FNR]-min>1){
    printf("%"a[FNR]-min"s%s\n",OFS,$NF)
  }
  else{
    print $NF
  }
}
' Input_file  Input_file

For shown samples output will be as follows.

switch_mm_irqs_off
   load_new_mm_cr3
finish_task_switch
smp_reschedule_interrupt
scheduler_ipi
   irq_enter
      rcu_irq_enter
      rcu_nmi_enter
   sched_ttwu_pending

Upvotes: 2

Shawn
Shawn

Reputation: 52334

Once you count the number of spaces between the function: and the top-level names, it's easy to do with sed:

$ sed 's/^.* function: \{13\}//' input.txt 
switch_mm_irqs_off
   load_new_mm_cr3
finish_task_switch
smp_reschedule_interrupt
scheduler_ipi
   irq_enter
      rcu_irq_enter
      rcu_nmi_enter
   sched_ttwu_pending

This just uses s// to remove everything extraneous to what your results should be. \{13\} in the regular expression matches 13 spaces (There's a leading space there that inline code markup eats; but it's obvious in the code block).

Upvotes: 2

Related Questions