SHELL: Variable output - bash

I need help. I have this shell script that will output the hdd status, but the variable $disk is not read in the echo to show result.
disk="sda1"
echo -n $(df -hl | grep '$disk' | awk ' {percent+=$5;} END{print percent}'| column -t ):

In bash, variables are not expanded when put inside single quotes. Use double quotes:
echo -n $(df -hl | grep "$disk")

Related

How to trim a string in shell script

I have a string,
var=refs/heads/testing/branch
I want to get rid of refs/heads/ in the string using shell script, such that I have only:
var=testing/branch
Commands I tried (one per line):
echo $(var) | awk -F\\ {'print $2'}
echo $var | sed -e s,refs/heads/,,
echo "refs/heads/testing/branch" | grep -oP '(?<=refs/heads/\)\w+'
echo "refs/heads/testing/branch" | LC_ALL=C sed -e 's/.*\\//'
echo "refs/heads/testing/branch" | cut -d'\' -f2
echo refs/heads/testing/branch | sed -e s,refs/heads/,,
there are lots of options out there ,try easy ones:
echo $var | cut -d "/" -f 3,4
echo $var | awk -F"/" '{print $3"/"$4}'
Shell parameter expansion: remove the prefix "refs/heads/" from the variable contents
$ var=refs/heads/testing/branch
$ echo "${var#refs/heads/}"
testing/branch

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

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

Using variables with grep is not working

I have a file VALIDATION_CONFIG_FILE.cfg which contains the records below:
ES_VDF_1|1
DE_VDF_1|2
ES_VDF_1|7
When I am using the grep command below by using variable then the command is returning ES_VDF_1 output. As per my understanding, command should not give any results. When I use the same command without using variables (use values directly) then command is returning no results, which is as expected. So what is the problem with variables which I am using?
FEED_ID_1_7="HU_VDF_1"
FEED_ID_2_7="ES_VDF_1"
FEED_ID_3_7="PT_VDF_2"
awk -F'|' '{ if($2=="7") print $1; }' VALIDATION_CONFIG_FILE.cfg |
grep -E -v '${FEED_ID_1_7}|${FEED_ID_2_7}|${FEED_ID_3_7}'
Output: ES_VDF_1
awk -F'|' '{ if($2=="7") print $1; }' VALIDATION_CONFIG_FILE.cfg |
grep -E -v 'ES_VDF_1|HU_VDF_1|PT_VDF_2'
Output: nothing
The problem you are seeing is that single quotes in Bash do not interpolate variables, whereas double quotes do.
For example with a variable imaginatively called "VARIABLE":
alex#yuzu:~$ export VARIABLE="foo"
If you echo it with double quotes, it is interpolated and the value of the variable is used:
alex#yuzu:~$ echo "$VARIABLE"
foo
But if you use single quotes the literal string '$VARIABLE' is used instead:
alex#yuzu:~$ echo '$VARIABLE'
$VARIABLE
The same goes for your grep.
grep -E -v '${FEED_ID_1_7}|${FEED_ID_2_7}|${FEED_ID_3_7}'
Should be:
grep -E -v "${FEED_ID_1_7}\|${FEED_ID_2_7}\|${FEED_ID_3_7}"
For example:
alex#yuzu:~$ echo "foo" | grep -E "$VARIABLE|$HOME|$USER"
foo
alex#yuzu:~$ echo "foo" | grep -E '$VARIABLE|$HOME|$USER'
[ no output ]
This is happening due to quotes.
Single quotes won't interpolate anything, but double quotes will do. Replace single quotes to double quotes with variables like below :
awk -F'|' '{ if($2=="7") print $1; }' VALIDATION_CONFIG_FILE.cfg |
grep -E -v "${FEED_ID_1_7}|${FEED_ID_2_7}|${FEED_ID_3_7}"
Refer bash manual for more details
Adding to Kaoru/Nishu Tayal's answer, you can make it safer further by using normal text search with fgrep and multiple -e:
fgrep -v -e "${FEED_ID_1_7}" -e "${FEED_ID_2_7}" -e "${FEED_ID_3_7}"
This would help prevent misinterpretations just in case special characters would be added to the values of variables.
If you don't have fgrep try grep -F.

Variable expanding in a script shell

My code is:
nb_lignes=`wc -l $1 | cut -d " " -f1`
for i in $(seq $(($nb_lignes - 1)) )
do
machine=`head $1 -n $i | tail -1`
machine1=`head $1 -n $nb_lignes | tail -1`
ssh root#$machine -x " scp /home/file.txt root#$machine1:/home && rm -r /home/file.txt"
done
Is $machine1 taken as a variable or a string? If a string, how can I change it — by adding a quote?
$machine will expand to head $1 -n $i | tail -1 result, $machine1 will expand to head $1 -n $nb_lignes | tail -1 result.
You could figured it out by yourself.
Btw, ssh root# …
$machine1 will be expanded to give the value of variable machine1, because you are using double quotes". If you had used single quotes ' then it would not have been expanded.
One possible confusion is when you embed a variable inside other text. In this case you are fine, because the trailing character is a : (root#$machine1:/home) which is not a valid character in a Bash variable name. Some shells (csh) would not have liked that, if you are not sure then you can delimit the variable name using { }, for example:
root#${machine1}:/home

How do I echo $command without breaking the layout

I'm trying to do the following in a bash script:
com=`ssh host "ls -lh"`
echo $com
It works, but the echo will break the output (instead of getting all lines in a column, I get them all in a row).
If I do: ssh host ls -lh in the CLI it will give me the correct output and layout.
How can I preserve the layout when echoing a variable?
You need:
echo "$com"
The quotes make the shell not break the value up into "words", but pass it as a single argument to echo.
Put double quotes around $com:
com=`ssh host "ls -lh"`
printf "%s" $com | tr -dc '\n' | wc -c # count newlines
printf "%s" "$com" | tr -dc '\n' | wc -c
echo "$com"

Resources