BASH:Why is printf to a var removing spaces? [duplicate] - bash

This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
I just assigned a variable, but echo $variable shows something else
(7 answers)
Closed 2 years ago.
Why is the output of these two different? I want the spaces to be preserved.
#!/bin/bash
x="foo"
printf "%-12s *" $x
echo " "
y=$(printf "%-12s" $x)
echo $y "*"
Running it gives
foo *
foo *
I want the second line to look like the first.

You'll need to quote the $y:
echo "${y} *"
#!/bin/bash
x="foo"
printf "%-12s *" $x
echo " "
y=$(printf "%-12s" $x)
echo "$y" "*"
➜ ./test.sh
foo *
foo *
➜
More information about when to use double quotes

Ypu can use printf too
printf '%s *\n' "$y"

Related

`echo` is stripping newlines in Bash script [duplicate]

This question already has answers here:
I just assigned a variable, but echo $variable shows something else
(7 answers)
When should I double-quote a parameter expansion? [duplicate]
(1 answer)
Closed 5 months ago.
If I have a file containing newlines, the below script will output the file as is, with newlines:
#!/bin/bash
FOO=$(cat filename.yaml)
echo "$FOO"
but
#!/bin/bash
FOO=$(cat filename.yaml)
FOO=$(echo $FOO)
echo "$FOO"
outputs the file all on one line. How come?
I do not recommend storing the contents of entire files in a single variable. In my experience that can have unpredictable results.
/usr/bin/env bash -x
index=$(wc -l filename.yaml | cut -d' ' -f1)
count=1
next () {
[[ "${count}" -lt "${index}" ]] && main
[[ "${count}" -eq "${index}" ]] && exit 0
}
main () {
line=$(sed -n "${count}p" filename.yaml)
echo "var${count}=${line}" >> varfile
count=$(($count+1))
next
}
next
If you source varfile at the start of another script, it will give you every line from that file, in its' own variable.

Is there a better way to echo without a newline in bash than using tr -d? [duplicate]

This question already has answers here:
"echo -n" prints "-n"
(11 answers)
Closed 3 years ago.
I have a script that counts down from 5 to 0:
for a in {5..0}; do echo $a | tr -d \\n; sleep 1; echo -e \\b | tr -d \\n; done
and tacking on tr -d just looks redundant and not very elegant to me. Is there a way to echo on one line without having to delete the newline?
You can use -n flag with echo:
for a in {5..0}; do echo -n $a; sleep 1; echo -ne \\b; done
Or just use printf:
for a in {5..0}; do printf $a; sleep 1; printf \\b; done
Note that this will show invalid numbers if counting from numbers greater or equal to 10. You could use \r carriage return character and clear the line with space, for example assume maximum number of 20 digits and use left formatting and fill the line with spaces:
for a in {20..0}; do printf "\r%-20d" "$a"; sleep 1; done
With bash COLUMNS variable and with * parameter passed width specifier with printf you could fill the whole line with spaces:
for a in {20..0}; do printf "\r%-*d" "$COLUMNS" "$a"; sleep 1; done
Or use a ansi escape sequence to clear the line:
for a in {20..0}; do printf "\r\033[K%d" "$a"; sleep 1; done

Missing new lines in Bash in passing function to variable [duplicate]

This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
Closed 1 year ago.
Why in this case doesnt generate new lines in Bash:
#!/bin/bash
function sample() {
local DATA=""
DATA="test1"$'\n'
DATA="${DATA}test2"$'\n'
echo ${DATA}
}
DATA=$(sample)
printf "%s" "${DATA}"
$DATA is expanded, and all whitespace (including newlines) are used for word-splitting, before echo ever runs. You should always quote parameters expansions.
sample() {
local DATA=""
DATA="test1"$'\n'
DATA="${DATA}test2"$'\n'
echo "${DATA}"
}
You must use the -e option of echo for it to interpret the \n character:
echo -e "${DATA}"

Print blank space in bash script [duplicate]

This question already has answers here:
I just assigned a variable, but echo $variable shows something else
(7 answers)
How to store output from printf with formatting in a variable? [duplicate]
(2 answers)
Closed 4 years ago.
Why such script:
x=xxx
y=yyy
printf -v var "%s %s" "$x" "$y"
printf $var
prints only:
xxx
While I expected:
xxx yyy
How to force printf not ignore symbols after blank space?
How about
#!/bin/bash
x=xxx
y=yyy
var=`printf "%s %s" $x $y`
echo $var
?

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=""

Resources