2

I have a string in variable and I would like to substitute it with another string, but the operation has no effect when the string being matched contains backslashes.

This is the part of the script that doesn't work:

cpuQueueOutput=`/usr/local/nagios/libexec/check_nrpe -H $hostname -t 30 -c Check_Pdh -a 'counter=\System\Processor Queue Length'`
echo "CPU Queue1: $cpuQueueOutput"
matchCpuQueueOutput="\System\Processor"
newCpuQueueOutput="CPU Queue"
CpuQueuePerf=`echo ${cpuQueueOutput//$matchCpuQueueOutput/$newCpuQueueOutput}`
echo "CPU Queue2: $CpuQueuePerf"

The output from the script looks like this:

CPU Queue1: OK: |'\System\Processor Queue Length_value'=0;0;0
CPU Queue2: OK: |'\System\Processor Queue Length_value'=0;0;0
OK: CPU Stats {(total, avg 1m: 9%), (total, avg 5m: 3%)} Top 3 Processes: {(powershell : 64%), (svchost#3 : 0%), (svchost#2 : 0%)} | 'total 1m'=9%;90;95 'total 5m'=3%;90;95

The substitution to replace OK: |'\System\Processor Queue Length_value' by 'CPU Queue' does not work.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
willemdh
  • 796
  • 2
  • 13
  • 34
  • 1
    Your "complete script" appears to have cut off at window length on the first few lines. – Etan Reisner Jan 28 '15 at 15:01
  • why do you need to `echo`? What's wrong with `EVALSTRING=${CPUOUTPUT//$MATCHEVALSTRING/$NEWEVALSTRING}`? – choroba Jan 28 '15 at 15:06
  • the prblem is in this part: CPUQUEUEOUTPUT=`/usr/local/nagios/libexec/check_nrpe -H $HOSTNAME -t 30 -c Check_Pdh -a 'counter=\System\Pr$ echo "CPU Queue1: $CPUQUEUEOUTPUT" MATCHCPUQUEUEOUTPUT="Processor" NEWCPUQUEUEOUTPUT="CPU Queue" CPUQUEUEPERF=`echo ${CPUQUEUEOUTPUT//$MATCHHCPUQUEUEOUTPUT/$NEWCPUQUEUEOUTPUT}` echo "CPU Queue2: $CPUQUEUEPERF" – willemdh Jan 28 '15 at 15:12
  • EVALSTRING=${CPUOUTPUT//$MATCHEVALSTRING/$NEWEVALSTRING} works correctly CPUQUEUEPERF=`echo ${CPUQUEUEOUTPUT//$MATCHHCPUQUEUEOUTPUT/$NEWCPUQUEUEOUTPUT}` does not work – willemdh Jan 28 '15 at 15:14
  • Basically I need to replace "OK: |'\System\Processor Queue Length_value'" by "'CPU Queue'" – willemdh Jan 28 '15 at 15:18
  • @user2961029: It would probably work better if you spelled `$MATCHHCPUQUEUEOUTPUT` consistently. (How many H's are there?) – rici Jan 28 '15 at 15:21
  • 1
    @user2961029: It's a common myth that it is good style to use ALLCAPS for bash variable names. It is not good style. All caps variables are used by the OS and by the shell. You should just use ordinary names, either with camelCase or with underscores, to make your variable names readable. (`match_cpu_queue_output`, for example). – rici Jan 28 '15 at 15:22
  • It does seem to work now when I use only system, but when I use a backslash in the match it doesn't work anymore. Tried escaping but does not seem to work. So this does not work: cpuQueueOutput=`/usr/local/nagios/libexec/check_nrpe -H $hostname -t 30 -c Check_Pdh -a 'counter=\System\Processor Queue Length'` echo "CPU Queue1: $cpuQueueOutput" matchCpuQueueOutput="\System\Processor" newCpuQueueOutput="CPU Queue" CpuQueuePerf=`echo ${cpuQueueOutput//$matchCpuQueueOutput/$newCpuQueueOutput}` echo "CPU Queue2: $CpuQueuePerf" – willemdh Jan 28 '15 at 15:31
  • BTW, in the future, you'd probably get a faster answer if you asked your question with sample code that people could copy and paste to run without needing to have Nagios (or other external tools) configured. – Charles Duffy Jan 28 '15 at 15:43

1 Answers1

2

Use more quotes!

# $'' makes the shell interpret backslashes, for easier embedding of single quotes
# inside a single-quoted string.
s=$'|\'\\System\\Processor Queue Length_value\'=0;0;0'
match="\System\Processor"
replace="CPU Queue"
echo "${s//"$match"/$replace}" # ignore StackOverflow's incorrect syntax highlighting

...as opposed to...

echo "${s//$match/$replace}"

This works because quoting an expansion in a pattern-match context in bash makes the result of that expansion literal -- and the backslashes need to be treated as literal to match themselves.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • This seems to work! Thanks Charles. I'll remember to make a sample code next time. Thanks for the tip. – willemdh Jan 28 '15 at 15:45