I'm trying to add the output of a command to the output of another command.
Output of first command:
-changing number of heading lines -
| Interface | Hostname | Speed |
| dl29 | host1 | 10Gbit |
| dl27 | host2 | 10Gbit |
-end of output-
Output of second command:
dl27=Time: 1day 30min 3sec
dl29=Time: 5min 55sec
Combined result should be:
-heading lines-
| Interface | Hostname | Speed |
| dl29 | host1 | 10Gbit | Time: 5min 55sec
| dl27 | host2 | 10Gbit | Time: 1day 30min 3sec
Does anyone have an idea how to accomplish this?
CodePudding user response:
Given these two 'commands' in bash:
cmd_1(){
echo '| Interface | Hostname | Speed |
| dl29 | host1 | 10Gbit |
| dl27 | host2 | 10Gbit |'
}
cmd_2(){
echo 'dl27=Time: 1day 30min 3sec
dl29=Time: 5min 55sec'
}
You can redirect the commands into awk to get what you are looking for:
awk 'BEGIN{FS="\\|[[:blank:]]*|[[:blank:]]*\\|"}
FNR==NR{
lines[FNR]=$0
idx[$2]=FNR
next
}
FNR==1{
print lines[1]}
{
split($0,a,"=")
print lines[idx[a[1]]], a[2]
}
' <(cmd_1) <(cmd_2)
Prints:
| Interface | Hostname | Speed |
| dl27 | host2 | 10Gbit | Time: 1day 30min 3sec
| dl29 | host1 | 10Gbit | Time: 5min 55sec
CodePudding user response:
gawk -F'\\s*[=|]\\s*' 'NR == FNR { a[$1] = $2; next }
$2 in a { $0 = $0 " " a[$2] } 1' <(cmd1) <(cmd2)
Replace \\s with [^[:space:]] or [^ ] if your non-GNU-yet-still-using-bash system doesn't support it.
Gawk of course implies GNU Awk if that isn't obvious enough.
CodePudding user response:
Assumptions:
- each line of the 2nd set of output has a single
= - every data line from the 1st set of output has a matching line in the 2nd set of output
- final output lines should be in the same order as they appear in the 2nd set of output (ie, no need to sort any of the data lines)
Modifying dawg's functions to match OP's latest update:
cmd_1(){
echo '-changing number of heading lines -
| Interface | Hostname | Speed |
| dl29 | host1 | 10Gbit |
| dl27 | host2 | 10Gbit |
-end of output-'
}
cmd_2(){
echo 'dl27=Time: 1day 30min 3sec
dl29=Time: 5min 55sec'
}
One awk idea:
awk '
FNR==NR { split($0,arr,"=")
timings[arr[1]]=arr[2]
next
}
FNR==1 { print "-heading lines-"; next }
FNR==2 { print ; next }
$2 in timings { print $0,timings[$2] }
' <(cmd_2) <(cmd_1)
This generates:
-heading lines-
| Interface | Hostname | Speed |
| dl29 | host1 | 10Gbit | Time: 5min 55sec
| dl27 | host2 | 10Gbit | Time: 1day 30min 3sec
CodePudding user response:
$ awk '
NR == FNR { time[$1]=$2; next }
{ print $0 ($2 in time ? " " time[$2] : "") }
' FS='=' <(cat cmd2out) FS=' *[|] *' <(cat cmd1out)
-changing number of heading lines -
| Interface | Hostname | Speed |
| dl29 | host1 | 10Gbit | Time: 5min 55sec
| dl27 | host2 | 10Gbit | Time: 1day 30min 3sec
-end of output-
Replace cat cmd1out and cat cmd2out with your actual commands. Note the order in which they must be called, command 2 first.
