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

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

Related

Why is only the first line evaluated with IFS=' ' [duplicate]

This question already has answers here:
Unix read command with option -d and IFS variable combination
(2 answers)
What does the bash read -d '' do?
(2 answers)
Bash: assignment of variable on same line not altering echo behavior [duplicate]
(2 answers)
Bash variable assignment before command [duplicate]
(2 answers)
Closed 2 years ago.
I'm trying to split a multi-line string on spaces only, preserving line breaks:
IFS=' ' read a b c <<< "$(printf '%s\n' "foo" "bar" "baz")"; echo "a=[$a]"; echo "b=[$b]"; echo "c=[$c]"
Expected:
a=[foo
bar
baz
]
b=[]
c=[]
Actual:
a=[foo]
b=[]
c=[]
What am I missing? When I replace \n with \t it works as expected.
I'm using bash v5.0.18

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

Command line args with spaces [duplicate]

This question already has an answer here:
How can I preserve command line spaces in a linux application?
(1 answer)
Closed 3 years ago.
Invoking a shell script with command line arguments containing spaces is generally solved by enclosing the argument in quotes:
getParams.sh 'one two' 'foo bar'
Produces:
one two
foo bar
getParams.sh:
while [[ $# > 0 ]]
do
echo $1
shift
done
However, if a shell variable is first defined to hold the value of the arguments such as:
args="'one two' 'foo bar'"
then why does:
getParams.sh $args
not recognize the single quotes enclosing the grouped arguments? The output is:
'one
two'
'three
four'
How can I store command line arguments containing spaces into a variable so that when getParams is invoked, the arguments are grouped according to the quoted arguments just as in the original example?
Use an array:
args=('one two' 'foo bar')
getParams.sh "${args[#]}"
Using args="'one two' 'foo bar'" wont work, because the single quotes retain their literal value when inside double quotes.
To preserve multiple spaces in the arguments (and also handle special characters such as *), you should quote your variable:
while [[ $# -gt 0 ]]
do
echo "$1"
shift
done

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

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 =

bash: $(...) trims trailing empty lines. How to properly assign to variable a command's output? [duplicate]

This question already has an answer here:
How do you retain trailing newlines when storing command output in a variable?
(1 answer)
Closed 8 years ago.
[Context]
Eg.1:
a="$(echo $'\n\n\n\n\n')"; echo ${#a};
I see:
0
Eg.2:
a="$(echo $'\n\n\n\n\n_')"; echo ${#a};
I see:
6
[Problem / Question]
I need to keep all the trailing empty lines in the assignment to variable. How to rewrite the «Eg.1»? If it's possible, give the simplest solution.
[Solution]
I'll accept the variant 2 of the rici's answer.
to()
{
local to=${1};
IFS= read -rd '' ${to};
printf -v ${to} "${!to%$'\n'}";
};
…
# a="$(echo $'\n\n\n\n\n')"; # wrong
to a < <(echo $'\n\n\n\n\n');
…
# aVariable="$(some_command arg_1 … arg_n)"; # wrong assignment
to aVariable < <(some_command arg_1 … arg_n);
P.S. The lengths of the both lines (i.e., of the wrong line and of the valid line) above are almost equal.
Here are two solutions which will work with arbitrary commands:
1) add the extra character at the end and then delete it:
$ a="$(printf '\n\n\n\n\n'; echo _)"; a="${a%?}"; echo ${#a}
5
2) use read:
$ IFS= read -rd '' a < <(printf '\n\n\n\n\n'); echo ${#a}
5
The space between -d and '' is necessary; you need to provide an empty argument to the -d option, and -d'' doesn't do that.

Resources