How to remove leading whitespace from a string in Bash [duplicate] - bash

This question already has answers here:
How to trim whitespace from a Bash variable?
(52 answers)
Closed 7 years ago.
For example, I have a string, " some string", and I want to put "some string" in another string variable. How do I do that?
My code:
function get_title() {
t1=$(get_type "$1")
t2="ACM Transactions"
t3="ELSEVIER"
t4="IEEE Transactions"
t5="MIT Press"
if [ "$t1"=="$t2" ];
then
title=$(less "$1" | head -1)
elif [ "$t1"=="$t5" ];
then
title=$(less "$1" | head -3)
fi
echo "$title"
}
As you can see the $title can return unwanted whitespace in front of text in center aligned texts. I want to prevent that.

A robust and straightforward approach is to use sed e.g.
$ sed 's/^[[:space:]]*//' <<< "$var"
If you are willing to turn on extended globbing (shopt -s extglob), then the following will remove initial whitespace from $var:
"${var##+([[:space:]])}"
Example:
var=$' \t abc \t ' echo "=${var##+([[:space:]])}="
=abc =

Related

Extracting number from string in bash script [duplicate]

This question already has answers here:
Extract substring in Bash
(26 answers)
Closed 5 months ago.
I have multiple s3 buckets in AWS whose names are in the following syntax:
resource-4511-deployment-1srsi6fjy9uuk
web-4533-logbucket-dogx6k0n8967
pcnfile6511
5399-bucket-6dehb5uuiwd
I'd like to extract the 4 digit number from each of these names preferably without using multiple if else loops which is the solution I can think of right now. The output should basically be
4511
4533
6511
5399
You can use parameter expansion. Prefix and suffix removal return the strings before and after the four digits, you can then use the removal again to remove the prefix and suffix:
#!/bin/bash
for name in resource-4511-deployment-1srsi6fjy9uuk \
web-4533-logbucket-dogx6k0n8967 \
pcnfile6511 \
5399-bucket-6dehb5uuiwd
do
after=${name#*[0-9][0-9][0-9][0-9]}
before=${name%%[0-9][0-9][0-9][0-9]*}
num=${name#$before}
num=${num%$after}
echo $num
done
I'd use regex matching here.
I was hoping the pattern would be cleaner, but the data forces this:
re='(^|[^[:digit:]])([[:digit:]]{4})($|[^[:digit:]])'
start of string or a non-digit
followed by 4 digits
followed by end of string or a non-digit
for name in resource-4511-deployment-1srsi6fjy9uuk \
web-4533-logbucket-dogx6k0n8967 \
pcnfile6511 \
5399-bucket-6dehb5uuiwd
do
[[ $name =~ $re ]] && echo ${BASH_REMATCH[2]}
done
Assuming there's only one set of 4-digits in each string, one bash idea using a regex and the BASH_REMATCH[] array:
regex='([0-9]{4})'
for string in resource-4511-deployment-1srsi6fjy9uuk web-4533-logbucket-dogx6k0n8967 pcnfile6511 5399-bucket-6dehb5uuiwd
do
[[ "${string}" =~ $regex ]] && echo "${BASH_REMATCH[1]}"
done
This generates:
4511
4533
6511
5399
printf "pcnfile6511" | grep "[0-9][0-9][0-9][0-9]"
That seems to work, although it only will for four digit numbers.
Also...
printf "resource-4511-deployment-1srsi6fjy9uuk" | cut -d'-' -f2
That will work when you have delimiters.
For numbers at the end of a line...
printf "pcnfile6511" | tail -c 4
And for numbers at the beginning...
printf "5399-bucket-6dehb5uuiwd" | head -c 4

index of bash string item with ifs separator [duplicate]

This question already has answers here:
How do I split a string on a delimiter in Bash?
(37 answers)
Closed 1 year ago.
Let's say I have this string:
NAMES="Mike&George&Norma"
IFS=$'&'
for NAME in $NAMES
do
echo ${NAME}
done
So I can loop through the NAMES.
But what if I only need George, i.e. the name at index 1?
How can I get NAMES[1]?
If mapfile aka readarray is available/acceptable.
#!/usr/bin/env bash
names="Mike&George&Norma"
mapfile -td '&' name <<< "$names"
printf '%s\n' "${name[#]}"
Prints all elements/strings in between the &, so
printf '%s\n' "${name[0]}"
printf '%s\n' "${name[1]}"
printf '%s\n' "${name[2]}"
Should print them names one by one.
See the builtin section of the bash manual https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html
$ NAMES="Mike&George&Norma";
$ echo "$NAMES" | cut -d'&' -f2
George
field counting starts with 1, unlike array indexing.
Using OP's current code one idea would be to add a counter to the loop processing, eg:
NAMES="Mike&George&Norma"
loop_ctr=-1
match_ctr=1
origIFS="${IFS}" # save current IFS
IFS=$'&'
for NAME in $NAMES
do
((loop_ctr++))
[[ "${loop_ctr}" -ne "${match_ctr}" ]] && # if loop_ctr != match_ctr then skip to next pass through loop
continue
echo ${NAME}
done
IFS="${origIFS}" # reset to original IFS
This generates as output:
George
NOTE: My preference would be to parse the string into an array (via mapfile/readarray) ... and #jetchisel beat me to that idea :-)

How to compare a variable to a string in bash? [duplicate]

This question already has answers here:
How do I compare two string variables in an 'if' statement in Bash? [duplicate]
(12 answers)
Closed 2 years ago.
here is how i tried it
while IFS= read line
do
var=$(cut -d ":" -f 3 $line)
if [ "$var" = "L2" ]
then :here is my action:
fi
done < myfile.txt
What i want to do is read a file line by line, read the third word of each line, and do a special action if the third word = a certaine string, i've tried a lot of syntax but it doesn't work. i've also tried to echo "$var" just to see if my variable get the right value, and it does. i don't know what to do anymore
It is better to use double brackets for if condition & for String comparison double equals (==)
And the line which has "cut" command wouldn't have worked. Please find below the corrected code which is working.
while IFS= read line
do
echo "Line is $line"
var=`echo $line | cut -d ":" -f 3`
echo $var
if [[ "$var" == "L2" ]]
then
echo "Some Action"
fi
done < myfile.txt

What is the difference between "$a" and $a in unix [duplicate]

This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
Closed 6 years ago.
For example:
#!/bin/sh
a=0
while [ "$a" -lt 10 ]
b="$a"
while [ "$b" -ge 0 ] do
echo -n "$b "
b=`expr $b - 1`
done
echo
a=`expr $a + 1`
done*
The above mentioned script gives the answer in triangle while with out the double quotes, it falls one after the other on diff lines.
After a variable is expanded to its value, word splitting (i.e. separating the value into tokens at whitespace) and filename wildcard expansion takes place unless the variable is inside double quotes.
Example:
var='foo bar'
echo No quotes: $var
echo With quotes: "$var"
will output:
No quotes: foo bar
With quotes: foo bar
Here the difference is how the argument is passed to echo function. Effectively " " will preserve whitespaces.
This:
echo -n "$b "
Is translated to:
echo -n "<number><space>"
While this:
echo -n $b<space>
Will ignore the trailing space and will just output the number:
echo -n <number>
Therefore removing all the spaces that are needed for output to look "triangular".
There are errors in your script:
no do after 1st while
no ; before do after 2nd while
why asterisk on done* at the end?
Now to answer your question.
If used as a paramenter:
"$a" is one argument.
$a (without quotes) is possibly multiple arguments:
Compare:
v='a b'; set $v; echo "\$#=$#, \$1=\"$1\", \$2=\"$2\""
$#=2, $1="a", $2="b"
v='a b'; set "$v"; echo "\$#=$#, \$1=\"$1\", \$2=\"$2\""
$#=1, $1="a b", $2=""

How to preserve trailing whitespace in bash function arguments? [duplicate]

This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
Closed 3 years ago.
Consider the following bash script:
#!/bin/bash
function foo {
echo -n $1
echo $2
}
foo 'Testing... ' 'OK' # => Testing...OK
# Whitespace --^ ^
# Missing whitespace -----------------^
What happened to the trailing whitespace in the first argument? How can preserve it?
What happened to the trailing whitespace in the first argument?
The whitespace was included on the echo command line, but was discarded by the shell, the same as if you had typed:
echo -n Testing...
^
|----- there is a space here
How can preserve it?
Quote your variables:
function foo {
echo -n "$1"
echo "$2"
}

Resources