"awk" and "cut" behaving differently in bash script - bash

I'm trying to cut the below string starting on the single quote:
name1=O'Reilly
so it leaves:
name2=Reilly
That's easy from the command line with the following commands:
echo $name | cut -d\' -f
echo $name | awk -F\' '{print $2}'
However when I run these commands from a script the string remains unaltered. I've been looking into problems with using single quotes as a delimiter but couldn't find anything. Any way to solve this issue?

That does not change the string the variable expands to, it just outputs the result of string manipulation.
If you want to create a new reference for variable name, use command substitution to save the result of cut/awk operation as variable name:
% name="O'Reilly"
% echo "$name" | awk -F\' '{print $2}'
Reilly
% name=$(echo "$name" | awk -F\' '{print $2}')
% echo "$name"
Reilly
On the other hand, if you want to declare the input as one (name1), and save the output as a different variable (name2):
% name1="O'Reilly"
% name2=$(echo "$name1" | awk -F\' '{print $2}')
% echo "$name2"
Reilly
This might be easier to get using Parameter expansion though:
$ name="O'Reilly"
$ echo "${name#*\'}"
Reilly
$ name="${name#*\'}"
$ echo "$name"
Reilly

Related

grep not finding name in text file

text file:
Annemie;014588529
Stefaan;011802367
Jan;032569874
Hans;015253694
Trying to find the phonenumber by name but it doesn't display anything
echo -n ""
read name
number=`grep '$name' numbers.txt | awk -F';' '{print $2}'`
echo "$number"
Single quotes avoid expansion of variables.
You are searching the string $name inside numbers.txt.
Try this instead:
echo -n ""
read name
number=$(grep "$name" numbers.txt | awk -F';' '{print $2}')
echo "$number"
or even better to reduce the pipe (awk can perform the grep directly):
echo -n ""
read name
number=$(awk -F';' -v name="$name" '$1 ~ name {print $2}' numbers.txt)
echo "$number"
Single quotes prevent the shell variable name to expand.
Try like this:
#!/bin/sh
read -p "Enter name: " name
number=$(grep -F "$name" numbers.txt | awk -F';' '{print $2}')
echo "$name => $number"
Also, you should use -F for fixed string grepping, avoid old-style backtick command substitution, and use $(..) instead. If you wish, you can use -p for read prompt (in POSIX shells, sh/bash included).

Need to generate files based on the value available in a variable in shell

In my script I have a variable $var which will hold a value "00135 00136 00137". I want to generate three files based on the values available in $var - if possible without using a loop.
For example, I need touch files with these names:
test.00136.txt
test.00137.txt
test.00138.txt
Avioding a while loop is possible with xargs.
First split the var into lines, use the string num as a placeholder and touch the files:
var="000135 00136 00137 00138 00139"
echo "${var}" | tr " " "\n" | xargs -I num touch test.num.txt
Edit:
Avoid tr with
echo -n "$var" | xargs -d' ' -n1 -Inum echo test.num.txt
The awk utility makes processing columnar data quite simple:
var="00135 00136 00137"
var1=$(echo "$var" | awk '{print $1}')
var2=$(echo "$var" | awk '{print $2}')
var3=$(echo "$var" | awk '{print $3}')
touch "test.${var1}.txt"
touch "test.${var2}.txt"
touch "test.${var3}.txt"

Split String in Unix Shell Script

I have a String like this
//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf
and want to get last part of
00000000957481f9-08d035805a5c94bf
Let's say you have
text="//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf"
If you know the position, i.e. in this case the 9th, you can go with
echo "$text" | cut -d'/' -f9
However, if this is dynamic and your want to split at "/", it's safer to go with:
echo "${text##*/}"
This removes everything from the beginning to the last occurrence of "/" and should be the shortest form to do it.
For more information on this see: Bash Reference manual
For more information on cut see: cut man page
The tool basename does exactly that:
$ basename //ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf
00000000957481f9-08d035805a5c94bf
I would use bash string function:
$ string="//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf"
$ echo "${string##*/}"
00000000957481f9-08d035805a5c94bf
But following are some other options:
$ awk -F'/' '$0=$NF' <<< "$string"
00000000957481f9-08d035805a5c94bf
$ sed 's#.*/##g' <<< "$string"
00000000957481f9-08d035805a5c94bf
Note: <<< is herestring notation. They do not create a subshell, however, they are NOT portable to POSIX sh (as implemented by shells such as ash or dash).
In case you want more than just the last part of the path,
you could do something like this:
echo $PWD | rev | cut -d'/' -f1-2 | rev
You can use this BASH regex:
s='//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf'
[[ "$s" =~ [^/]+$ ]] && echo "${BASH_REMATCH[0]}"
00000000957481f9-08d035805a5c94bf
This can be done easily in awk:
string="//ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf"
echo "${string}" | awk -v FS="/" '{ print $NF }'
Use "/" as field separator and print the last field.
You can try this...
echo //ABC/REC/TLC/SC-prod/1f9/20/00000000957481f9-08d035805a5c94bf |awk -F "/" '{print $NF}'

Pass variable to nawk in bash?

I'm trying to pass a variable to nawk in a bash script, but it's not actually printing the $commentValue variable's contents. Everything works great, except the last part of the printf statement. Thanks!
echo -n "Service Name: "
read serviceName
echo -n "Comment: "
read commentValue
for check in $(grep "CURRENT SERVICE STATE" $nagiosLog |grep -w "$serviceName" | nawk -F": " '{print $2}' |sort -u ) ; do
echo $check | nawk -F";" -v now=$now '{ printf( "[%u]=ACKNOWLEDGE_SVC_PROBLEM;"$1";"$2";2;1;0;admin;$commentValue"\n", now)}' >> $nagiosCommand
done
$commentValue is inside an invocation to nawk, so it is considered as a variable in nawk, not a variable in bash. Since you do not have such a variable in nawk, you won't get anything there. You should first pass the variable "inside" nawk using the -v switch just like you did for the now variable; i.e.:
... | nawk -F";" -v now=$now -v "commentValue=$commentValue"
Note the quotes - they are required in case $commentValue contains whitespace.

Bash awk one-liner not printing

Expecting this to print out abc - but I get nothing, every time, nothing.
echo abc=xyz | g="$(awk -F "=" '{print $1}')" | echo $g
A pipeline isn't a set of separate assignments. However, you could rewrite your current code as follows:
result=$(
echo 'abc=xyz' | awk -F '=' '{print $1}'
)
echo "$result"
However, a more Bash-centric solution without intermediate assignments could take advantage of a here-string. For example:
awk -F '=' '{print $1}' <<< 'abc=xyz'
Other solutions are possible, too, but this should be enough to get you started in the right direction.

Resources