I have a shell script with this code:
var=`hg st -R "$path"`
if [ -n "$var" ]; then
echo $var
fi
But the conditional code always executes, because hg st
always prints at least one newline character.
$var
(like trim()
in PHP)?or
I could use sed or AWK, but I'd like to think there is a more elegant solution to this problem.
I've always done it with sed
var=`hg st -R "$path" | sed -e 's/ *$//'`
If there is a more elegant solution, I hope somebody posts it.
You can delete newlines with tr
:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done
I created the following functions. I am not sure how portable printf is, but the beauty of this solution is you can specify exactly what is "white space" by adding more character codes.
iswhitespace()
{
n=`printf "%d\n" "'$1'"`
if (( $n != "13" )) && (( $n != "10" )) && (( $n != "32" )) && (( $n != "92" )) && (( $n != "110" )) && (( $n != "114" )); then
return 0
fi
return 1
}
trim()
{
i=0
str="$1"
while (( i < ${#1} ))
do
char=${1:$i:1}
iswhitespace "$char"
if [ "$?" -eq "0" ]; then
str="${str:$i}"
i=${#1}
fi
(( i += 1 ))
done
i=${#str}
while (( i > "0" ))
do
(( i -= 1 ))
char=${str:$i:1}
iswhitespace "$char"
if [ "$?" -eq "0" ]; then
(( i += 1 ))
str="${str:0:$i}"
i=0
fi
done
echo "$str"
}
#Call it like so
mystring=`trim "$mystring"`
Removing spaces to one space:
(text) | fmt -su
This worked for me:
text=" trim my edges "
trimmed=$text
trimmed=${trimmed##+( )} #Remove longest matching series of spaces from the front
trimmed=${trimmed%%+( )} #Remove longest matching series of spaces from the back
echo "<$trimmed>" #Adding angle braces just to make it easier to confirm that all spaces are removed
#Result
<trim my edges>
To put that on fewer lines for the same result:
text=" trim my edges "
trimmed=${${text##+( )}%%+( )}
You can delete newlines with tr
:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done
Use this simple Bash parameter expansion:
$ x=" a z e r ty "
$ echo "START[${x// /}]END"
START[azerty]END
Bash has a feature called parameter expansion, which, among other things, allows string replacement based on so-called patterns (patterns resemble regular expressions, but there are fundamental differences and limitations). [flussence's original line: Bash has regular expressions, but they're well-hidden:]
The following demonstrates how to remove all white space (even from the interior) from a variable value.
$ var='abc def'
$ echo "$var"
abc def
# Note: flussence's original expression was "${var/ /}", which only replaced the *first* space char., wherever it appeared.
$ echo -n "${var//[[:space:]]/}"
abcdef
Yet another solution with unit tests which trims $IFS
from stdin, and works with any input separator (even $'\0'
):
ltrim()
{
# Left-trim $IFS from stdin as a single line
# $1: Line separator (default NUL)
local trimmed
while IFS= read -r -d "${1-}" -u 9
do
if [ -n "${trimmed+defined}" ]
then
printf %s "$REPLY"
else
printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
fi
printf "${1-\x00}"
trimmed=true
done 9<&0
if [[ $REPLY ]]
then
# No delimiter at last line
if [ -n "${trimmed+defined}" ]
then
printf %s "$REPLY"
else
printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
fi
fi
}
rtrim()
{
# Right-trim $IFS from stdin as a single line
# $1: Line separator (default NUL)
local previous last
while IFS= read -r -d "${1-}" -u 9
do
if [ -n "${previous+defined}" ]
then
printf %s "$previous"
printf "${1-\x00}"
fi
previous="$REPLY"
done 9<&0
if [[ $REPLY ]]
then
# No delimiter at last line
last="$REPLY"
printf %s "$previous"
if [ -n "${previous+defined}" ]
then
printf "${1-\x00}"
fi
else
last="$previous"
fi
right_whitespace="${last##*[!$IFS]}"
printf %s "${last%$right_whitespace}"
}
trim()
{
# Trim $IFS from individual lines
# $1: Line separator (default NUL)
ltrim ${1+"$@"} | rtrim ${1+"$@"}
}
With Bash's extended pattern matching features enabled (shopt -s extglob
), you can use this:
{trimmed##*( )}
to remove an arbitrary amount of leading spaces.
In order to remove all the spaces from the beginning and the end of a string (including end of line characters):
echo $variable | xargs echo -n
This will remove duplicate spaces also:
echo " this string has a lot of spaces " | xargs echo -n
Produces: 'this string has a lot of spaces'
#!/bin/bash
function trim
{
typeset trimVar
eval trimVar="\${$1}"
read trimVar << EOTtrim
$trimVar
EOTtrim
eval $1=\$trimVar
}
# Note that the parameter to the function is the NAME of the variable to trim,
# not the variable contents. However, the contents are trimmed.
# Example of use:
while read aLine
do
trim aline
echo "[${aline}]"
done < info.txt
# File info.txt contents:
# ------------------------------
# ok hello there $
# another line here $
#and yet another $
# only at the front$
#$
# Output:
#[ok hello there]
#[another line here]
#[and yet another]
#[only at the front]
#[]
Assignments ignore leading and trailing whitespace and as such can be used to trim:
$ var=`echo ' hello'`; echo $var
hello
You can trim simply with echo
:
foo=" qsdqsd qsdqs q qs "
# Not trimmed
echo \'$foo\'
# Trim
foo=`echo $foo`
# Trimmed
echo \'$foo\'
This will remove all the whitespaces from your String,
VAR2="${VAR2//[[:space:]]/}"
/
replaces the first occurrence and //
all occurrences of whitespaces in the string. I.e. all white spaces get replaced by – nothing
#Execute this script with the string argument passed in double quotes !!
#var2 gives the string without spaces.
#$1 is the string passed in double quotes
#!/bin/bash
var2=`echo $1 | sed 's/ \+//g'`
echo $var2
Here's a trim() function that trims and normalizes whitespace
#!/bin/bash
function trim {
echo $*
}
echo "'$(trim " one two three ")'"
# 'one two three'
And another variant that uses regular expressions.
#!/bin/bash
function trim {
local trimmed="$@"
if [[ "$trimmed" =~ " *([^ ].*[^ ]) *" ]]
then
trimmed=${BASH_REMATCH[1]}
fi
echo "$trimmed"
}
echo "'$(trim " one two three ")'"
# 'one two three'
I found that I needed to add some code from a messy sdiff
output in order to clean it up:
sdiff -s column1.txt column2.txt | grep -F '<' | cut -f1 -d"<" > c12diff.txt
sed -n 1'p' c12diff.txt | sed 's/ *$//g' | tr -d '\n' | tr -d '\t'
This removes the trailing spaces and other invisible characters.
Removing spaces to one space:
(text) | fmt -su
A simple answer is:
echo " lol " | xargs
Xargs will do the trimming for you. It's one command/program, no parameters, returns the trimmed string, easy as that!
Note: this doesn't remove all internal spaces so "foo bar"
stays the same; it does NOT become "foobar"
. However, multiple spaces will be condensed to single spaces, so "foo bar"
will become "foo bar"
. In addition it doesn't remove end of lines characters.
Bash has a feature called parameter expansion, which, among other things, allows string replacement based on so-called patterns (patterns resemble regular expressions, but there are fundamental differences and limitations). [flussence's original line: Bash has regular expressions, but they're well-hidden:]
The following demonstrates how to remove all white space (even from the interior) from a variable value.
$ var='abc def'
$ echo "$var"
abc def
# Note: flussence's original expression was "${var/ /}", which only replaced the *first* space char., wherever it appeared.
$ echo -n "${var//[[:space:]]/}"
abcdef
There are a lot of answers, but I still believe my just-written script is worth being mentioned because:
"$*"
joins multiple arguments using one space. if you want to trim & output only the first argument, use "$1"
insteadThe script:
trim() {
local s2 s="$*"
until s2="${s#[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
until s2="${s%[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
echo "$s"
}
Usage:
mystring=" here is
something "
mystring=$(trim "$mystring")
echo ">$mystring<"
Output:
>here is
something<
I've seen scripts just use variable assignment to do the job:
$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar
Whitespace is automatically coalesced and trimmed. One has to be careful of shell metacharacters (potential injection risk).
I would also recommend always double-quoting variable substitutions in shell conditionals:
if [ -n "$var" ]; then
since something like a -o or other content in the variable could amend your test arguments.
You can trim simply with echo
:
foo=" qsdqsd qsdqs q qs "
# Not trimmed
echo \'$foo\'
# Trim
foo=`echo $foo`
# Trimmed
echo \'$foo\'
I've always done it with sed
var=`hg st -R "$path" | sed -e 's/ *$//'`
If there is a more elegant solution, I hope somebody posts it.
trim() removes whitespaces (and tabs, non-printable characters; I am considering just whitespaces for simplicity). My version of a solution:
var="$(hg st -R "$path")" # I often like to enclose shell output in double quotes
var="$(echo "${var}" | sed "s/\(^ *\| *\$\)//g")" # This is my suggestion
if [ -n "$var" ]; then
echo "[${var}]"
fi
The 'sed' command trims only leading and trailing whitespaces, but it can be piped to the first command as well resulting in:
var="$(hg st -R "$path" | sed "s/\(^ *\| *\$\)//g")"
if [ -n "$var" ]; then
echo "[${var}]"
fi
To remove spaces and tabs from left to first word, enter:
echo " This is a test" | sed "s/^[ \t]*//"
cyberciti.biz/tips/delete-leading-spaces-from-front-of-each-word.html
Use this simple Bash parameter expansion:
$ x=" a z e r ty "
$ echo "START[${x// /}]END"
START[azerty]END
# Strip leading and trailing white space (new line inclusive).
trim(){
[[ "$1" =~ [^[:space:]](.*[^[:space:]])? ]]
printf "%s" "$BASH_REMATCH"
}
OR
# Strip leading white space (new line inclusive).
ltrim(){
[[ "$1" =~ [^[:space:]].* ]]
printf "%s" "$BASH_REMATCH"
}
# Strip trailing white space (new line inclusive).
rtrim(){
[[ "$1" =~ .*[^[:space:]] ]]
printf "%s" "$BASH_REMATCH"
}
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "$(rtrim "$(ltrim "$1")")"
}
OR
# Strip leading and trailing specified characters. ex: str=$(trim "$str" $'\n a')
trim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
printf "%s" "${BASH_REMATCH[1]}"
}
OR
# Strip leading specified characters. ex: str=$(ltrim "$str" $'\n a')
ltrim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"]) ]]
printf "%s" "${BASH_REMATCH[1]}"
}
# Strip trailing specified characters. ex: str=$(rtrim "$str" $'\n a')
rtrim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
printf "%s" "${BASH_REMATCH[1]}"
}
# Strip leading and trailing specified characters. ex: str=$(trim "$str" $'\n a')
trim(){
printf "%s" "$(rtrim "$(ltrim "$1" "$2")" "$2")"
}
OR
Building upon moskit's expr soulution...
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)[[:space:]]*$"`"
}
OR
# Strip leading white space (new line inclusive).
ltrim(){
printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)"`"
}
# Strip trailing white space (new line inclusive).
rtrim(){
printf "%s" "`expr "$1" : "^\(.*[^[:space:]]\)[[:space:]]*$"`"
}
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "$(rtrim "$(ltrim "$1")")"
}
trim() removes whitespaces (and tabs, non-printable characters; I am considering just whitespaces for simplicity). My version of a solution:
var="$(hg st -R "$path")" # I often like to enclose shell output in double quotes
var="$(echo "${var}" | sed "s/\(^ *\| *\$\)//g")" # This is my suggestion
if [ -n "$var" ]; then
echo "[${var}]"
fi
The 'sed' command trims only leading and trailing whitespaces, but it can be piped to the first command as well resulting in:
var="$(hg st -R "$path" | sed "s/\(^ *\| *\$\)//g")"
if [ -n "$var" ]; then
echo "[${var}]"
fi
I would simply use sed:
function trim
{
echo "$1" | sed -n '1h;1!H;${;g;s/^[ \t]*//g;s/[ \t]*$//g;p;}'
}
a) Example of usage on single-line string
string=' wordA wordB wordC wordD '
trimmed=$( trim "$string" )
echo "GIVEN STRING: |$string|"
echo "TRIMMED STRING: |$trimmed|"
Output:
GIVEN STRING: | wordA wordB wordC wordD |
TRIMMED STRING: |wordA wordB wordC wordD|
b) Example of usage on multi-line string
string=' wordA
>wordB<
wordC '
trimmed=$( trim "$string" )
echo -e "GIVEN STRING: |$string|\n"
echo "TRIMMED STRING: |$trimmed|"
Output:
GIVEN STRING: | wordAA
>wordB<
wordC |
TRIMMED STRING: |wordAA
>wordB<
wordC|
c) Final note:
If you don't like to use a function, for single-line string you can simply use a "easier to remember" command like:
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Example:
echo " wordA wordB wordC " | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Output:
wordA wordB wordC
Using the above on multi-line strings will work as well, but please note that it will cut any trailing/leading internal multiple space as well, as GuruM noticed in the comments
string=' wordAA
>four spaces before<
>one space before< '
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Output:
wordAA
>four spaces before<
>one space before<
So if you do mind to keep those spaces, please use the function at the beginning of my answer!
d) EXPLANATION of the sed syntax "find and replace" on multi-line strings used inside the function trim:
sed -n '
# If the first line, copy the pattern to the hold buffer
1h
# If not the first line, then append the pattern to the hold buffer
1!H
# If the last line then ...
$ {
# Copy from the hold to the pattern buffer
g
# Do the search and replace
s/^[ \t]*//g
s/[ \t]*$//g
# print
p
}'
var=" a b "
echo "$(set -f; echo $var)"
>a b
I've always done it with sed
var=`hg st -R "$path" | sed -e 's/ *$//'`
If there is a more elegant solution, I hope somebody posts it.
trim()
{
local trimmed="$1"
# Strip leading space.
trimmed="${trimmed## }"
# Strip trailing space.
trimmed="${trimmed%% }"
echo "$trimmed"
}
For example:
test1="$(trim " one leading")"
test2="$(trim "one trailing ")"
test3="$(trim " one leading and one trailing ")"
echo "'$test1', '$test2', '$test3'"
Output:
'one leading', 'one trailing', 'one leading and one trailing'
trim()
{
local trimmed="$1"
# Strip leading spaces.
while [[ $trimmed == ' '* ]]; do
trimmed="${trimmed## }"
done
# Strip trailing spaces.
while [[ $trimmed == *' ' ]]; do
trimmed="${trimmed%% }"
done
echo "$trimmed"
}
For example:
test4="$(trim " two leading")"
test5="$(trim "two trailing ")"
test6="$(trim " two leading and two trailing ")"
echo "'$test4', '$test5', '$test6'"
Output:
'two leading', 'two trailing', 'two leading and two trailing'
Let's define a variable containing leading, trailing, and intermediate whitespace:
FOO=' test test test '
echo -e "FOO='${FOO}'"
# > FOO=' test test test '
echo -e "length(FOO)==${#FOO}"
# > length(FOO)==16
How to remove all whitespace (denoted by [:space:]
in tr
):
FOO=' test test test '
FOO_NO_WHITESPACE="$(echo -e "${FOO}" | tr -d '[:space:]')"
echo -e "FOO_NO_WHITESPACE='${FOO_NO_WHITESPACE}'"
# > FOO_NO_WHITESPACE='testtesttest'
echo -e "length(FOO_NO_WHITESPACE)==${#FOO_NO_WHITESPACE}"
# > length(FOO_NO_WHITESPACE)==12
How to remove leading whitespace only:
FOO=' test test test '
FOO_NO_LEAD_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//')"
echo -e "FOO_NO_LEAD_SPACE='${FOO_NO_LEAD_SPACE}'"
# > FOO_NO_LEAD_SPACE='test test test '
echo -e "length(FOO_NO_LEAD_SPACE)==${#FOO_NO_LEAD_SPACE}"
# > length(FOO_NO_LEAD_SPACE)==15
How to remove trailing whitespace only:
FOO=' test test test '
FOO_NO_TRAIL_SPACE="$(echo -e "${FOO}" | sed -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_TRAIL_SPACE='${FOO_NO_TRAIL_SPACE}'"
# > FOO_NO_TRAIL_SPACE=' test test test'
echo -e "length(FOO_NO_TRAIL_SPACE)==${#FOO_NO_TRAIL_SPACE}"
# > length(FOO_NO_TRAIL_SPACE)==15
How to remove both leading and trailing spaces--chain the sed
s:
FOO=' test test test '
FOO_NO_EXTERNAL_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_EXTERNAL_SPACE='${FOO_NO_EXTERNAL_SPACE}'"
# > FOO_NO_EXTERNAL_SPACE='test test test'
echo -e "length(FOO_NO_EXTERNAL_SPACE)==${#FOO_NO_EXTERNAL_SPACE}"
# > length(FOO_NO_EXTERNAL_SPACE)==14
Alternatively, if your bash supports it, you can replace echo -e "${FOO}" | sed ...
with sed ... <<<${FOO}
, like so (for trailing whitespace):
FOO_NO_TRAIL_SPACE="$(sed -e 's/[[:space:]]*$//' <<<${FOO})"
Assignments ignore leading and trailing whitespace and as such can be used to trim:
$ var=`echo ' hello'`; echo $var
hello
I had to test the result (numeric) from a command but it seemed the variable with the result was containing spaces and some non printable characters. Therefore even after a "trim" the comparison was erroneous. I solved it by extracting the numerical part from the variable:
numerical_var=$(echo ${var_with_result_from_command} | grep -o "[0-9]*")
# Trim whitespace from both ends of specified parameter
trim () {
read -rd '' $1 <<<"${!1}"
}
# Unit test for trim()
test_trim () {
local foo="$1"
trim foo
test "$foo" = "$2"
}
test_trim hey hey &&
test_trim ' hey' hey &&
test_trim 'ho ' ho &&
test_trim 'hey ho' 'hey ho' &&
test_trim ' hey ho ' 'hey ho' &&
test_trim $'\n\n\t hey\n\t ho \t\n' $'hey\n\t ho' &&
test_trim $'\n' '' &&
test_trim '\n' '\n' &&
echo passed
With Bash's extended pattern matching features enabled (shopt -s extglob
), you can use this:
{trimmed##*( )}
to remove an arbitrary amount of leading spaces.
There is a solution which only uses Bash built-ins called wildcards:
var=" abc "
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "===$var==="
Here's the same wrapped in a function:
trim() {
local var="$*"
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "$var"
}
You pass the string to be trimmed in quoted form. e.g.:
trim " abc "
A nice thing about this solution is that it will work with any POSIX-compliant shell.
#!/bin/bash
function trim
{
typeset trimVar
eval trimVar="\${$1}"
read trimVar << EOTtrim
$trimVar
EOTtrim
eval $1=\$trimVar
}
# Note that the parameter to the function is the NAME of the variable to trim,
# not the variable contents. However, the contents are trimmed.
# Example of use:
while read aLine
do
trim aline
echo "[${aline}]"
done < info.txt
# File info.txt contents:
# ------------------------------
# ok hello there $
# another line here $
#and yet another $
# only at the front$
#$
# Output:
#[ok hello there]
#[another line here]
#[and yet another]
#[only at the front]
#[]
You can use old-school tr
. For example, this returns the number of modified files in a git repository, whitespaces stripped.
MYVAR=`git ls-files -m|wc -l|tr -d ' '`
var=" a b "
echo "$(set -f; echo $var)"
>a b
This is what I did and worked out perfect and so simple:
the_string=" test"
the_string=`echo $the_string`
echo "$the_string"
Output:
test
Bash has a feature called parameter expansion, which, among other things, allows string replacement based on so-called patterns (patterns resemble regular expressions, but there are fundamental differences and limitations). [flussence's original line: Bash has regular expressions, but they're well-hidden:]
The following demonstrates how to remove all white space (even from the interior) from a variable value.
$ var='abc def'
$ echo "$var"
abc def
# Note: flussence's original expression was "${var/ /}", which only replaced the *first* space char., wherever it appeared.
$ echo -n "${var//[[:space:]]/}"
abcdef
This will remove all the whitespaces from your String,
VAR2="${VAR2//[[:space:]]/}"
/
replaces the first occurrence and //
all occurrences of whitespaces in the string. I.e. all white spaces get replaced by – nothing
I had to test the result (numeric) from a command but it seemed the variable with the result was containing spaces and some non printable characters. Therefore even after a "trim" the comparison was erroneous. I solved it by extracting the numerical part from the variable:
numerical_var=$(echo ${var_with_result_from_command} | grep -o "[0-9]*")
This does not have the problem with unwanted globbing, also, interior white-space is unmodified (assuming that $IFS
is set to the default, which is ' \t\n'
).
It reads up to the first newline (and doesn't include it) or the end of string, whichever comes first, and strips away any mix of leading and trailing space and \t
characters. If you want to preserve multiple lines (and also strip leading and trailing newlines), use read -r -d '' var << eof
instead; note, however, that if your input happens to contain \neof
, it will be cut off just before. (Other forms of white space, namely \r
, \f
, and \v
, are not stripped, even if you add them to $IFS.)
read -r var << eof
$var
eof
Bash has a feature called parameter expansion, which, among other things, allows string replacement based on so-called patterns (patterns resemble regular expressions, but there are fundamental differences and limitations). [flussence's original line: Bash has regular expressions, but they're well-hidden:]
The following demonstrates how to remove all white space (even from the interior) from a variable value.
$ var='abc def'
$ echo "$var"
abc def
# Note: flussence's original expression was "${var/ /}", which only replaced the *first* space char., wherever it appeared.
$ echo -n "${var//[[:space:]]/}"
abcdef
I found that I needed to add some code from a messy sdiff
output in order to clean it up:
sdiff -s column1.txt column2.txt | grep -F '<' | cut -f1 -d"<" > c12diff.txt
sed -n 1'p' c12diff.txt | sed 's/ *$//g' | tr -d '\n' | tr -d '\t'
This removes the trailing spaces and other invisible characters.
I've seen scripts just use variable assignment to do the job:
$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar
Whitespace is automatically coalesced and trimmed. One has to be careful of shell metacharacters (potential injection risk).
I would also recommend always double-quoting variable substitutions in shell conditionals:
if [ -n "$var" ]; then
since something like a -o or other content in the variable could amend your test arguments.
Yet another solution with unit tests which trims $IFS
from stdin, and works with any input separator (even $'\0'
):
ltrim()
{
# Left-trim $IFS from stdin as a single line
# $1: Line separator (default NUL)
local trimmed
while IFS= read -r -d "${1-}" -u 9
do
if [ -n "${trimmed+defined}" ]
then
printf %s "$REPLY"
else
printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
fi
printf "${1-\x00}"
trimmed=true
done 9<&0
if [[ $REPLY ]]
then
# No delimiter at last line
if [ -n "${trimmed+defined}" ]
then
printf %s "$REPLY"
else
printf %s "${REPLY#"${REPLY%%[!$IFS]*}"}"
fi
fi
}
rtrim()
{
# Right-trim $IFS from stdin as a single line
# $1: Line separator (default NUL)
local previous last
while IFS= read -r -d "${1-}" -u 9
do
if [ -n "${previous+defined}" ]
then
printf %s "$previous"
printf "${1-\x00}"
fi
previous="$REPLY"
done 9<&0
if [[ $REPLY ]]
then
# No delimiter at last line
last="$REPLY"
printf %s "$previous"
if [ -n "${previous+defined}" ]
then
printf "${1-\x00}"
fi
else
last="$previous"
fi
right_whitespace="${last##*[!$IFS]}"
printf %s "${last%$right_whitespace}"
}
trim()
{
# Trim $IFS from individual lines
# $1: Line separator (default NUL)
ltrim ${1+"$@"} | rtrim ${1+"$@"}
}
This does not have the problem with unwanted globbing, also, interior white-space is unmodified (assuming that $IFS
is set to the default, which is ' \t\n'
).
It reads up to the first newline (and doesn't include it) or the end of string, whichever comes first, and strips away any mix of leading and trailing space and \t
characters. If you want to preserve multiple lines (and also strip leading and trailing newlines), use read -r -d '' var << eof
instead; note, however, that if your input happens to contain \neof
, it will be cut off just before. (Other forms of white space, namely \r
, \f
, and \v
, are not stripped, even if you add them to $IFS.)
read -r var << eof
$var
eof
Python has a function strip()
that works identically to PHP's trim()
, so we can just do a little inline Python to make an easily understandable utility for this:
alias trim='python -c "import sys; sys.stdout.write(sys.stdin.read().strip())"'
This will trim leading and trailing whitespace (including newlines).
$ x=`echo -e "\n\t \n" | trim`
$ if [ -z "$x" ]; then echo hi; fi
hi
From Bash Guide section on globbing
To use an extglob in a parameter expansion
#Turn on extended globbing
shopt -s extglob
#Trim leading and trailing whitespace from a variable
x=${x##+([[:space:]])}; x=${x%%+([[:space:]])}
#Turn off extended globbing
shopt -u extglob
Here's the same functionality wrapped in a function (NOTE: Need to quote input string passed to function):
trim() {
# Determine if 'extglob' is currently on.
local extglobWasOff=1
shopt extglob >/dev/null && extglobWasOff=0
(( extglobWasOff )) && shopt -s extglob # Turn 'extglob' on, if currently turned off.
# Trim leading and trailing whitespace
local var=$1
var=${var##+([[:space:]])}
var=${var%%+([[:space:]])}
(( extglobWasOff )) && shopt -u extglob # If 'extglob' was off before, turn it back off.
echo -n "$var" # Output trimmed string.
}
Usage:
string=" abc def ghi ";
#need to quote input-string to preserve internal white-space if any
trimmed=$(trim "$string");
echo "$trimmed";
If we alter the function to execute in a subshell, we don't have to worry about examining the current shell option for extglob, we can just set it without affecting the current shell. This simplifies the function tremendously. I also update the positional parameters "in place" so I don't even need a local variable
trim() {
shopt -s extglob
set -- "${1##+([[:space:]])}"
printf "%s" "${1%%+([[:space:]])}"
}
so:
$ s=$'\t\n \r\tfoo '
$ shopt -u extglob
$ shopt extglob
extglob off
$ printf ">%q<\n" "$s" "$(trim "$s")"
>$'\t\n \r\tfoo '<
>foo<
$ shopt extglob
extglob off
Let's define a variable containing leading, trailing, and intermediate whitespace:
FOO=' test test test '
echo -e "FOO='${FOO}'"
# > FOO=' test test test '
echo -e "length(FOO)==${#FOO}"
# > length(FOO)==16
How to remove all whitespace (denoted by [:space:]
in tr
):
FOO=' test test test '
FOO_NO_WHITESPACE="$(echo -e "${FOO}" | tr -d '[:space:]')"
echo -e "FOO_NO_WHITESPACE='${FOO_NO_WHITESPACE}'"
# > FOO_NO_WHITESPACE='testtesttest'
echo -e "length(FOO_NO_WHITESPACE)==${#FOO_NO_WHITESPACE}"
# > length(FOO_NO_WHITESPACE)==12
How to remove leading whitespace only:
FOO=' test test test '
FOO_NO_LEAD_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//')"
echo -e "FOO_NO_LEAD_SPACE='${FOO_NO_LEAD_SPACE}'"
# > FOO_NO_LEAD_SPACE='test test test '
echo -e "length(FOO_NO_LEAD_SPACE)==${#FOO_NO_LEAD_SPACE}"
# > length(FOO_NO_LEAD_SPACE)==15
How to remove trailing whitespace only:
FOO=' test test test '
FOO_NO_TRAIL_SPACE="$(echo -e "${FOO}" | sed -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_TRAIL_SPACE='${FOO_NO_TRAIL_SPACE}'"
# > FOO_NO_TRAIL_SPACE=' test test test'
echo -e "length(FOO_NO_TRAIL_SPACE)==${#FOO_NO_TRAIL_SPACE}"
# > length(FOO_NO_TRAIL_SPACE)==15
How to remove both leading and trailing spaces--chain the sed
s:
FOO=' test test test '
FOO_NO_EXTERNAL_SPACE="$(echo -e "${FOO}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
echo -e "FOO_NO_EXTERNAL_SPACE='${FOO_NO_EXTERNAL_SPACE}'"
# > FOO_NO_EXTERNAL_SPACE='test test test'
echo -e "length(FOO_NO_EXTERNAL_SPACE)==${#FOO_NO_EXTERNAL_SPACE}"
# > length(FOO_NO_EXTERNAL_SPACE)==14
Alternatively, if your bash supports it, you can replace echo -e "${FOO}" | sed ...
with sed ... <<<${FOO}
, like so (for trailing whitespace):
FOO_NO_TRAIL_SPACE="$(sed -e 's/[[:space:]]*$//' <<<${FOO})"
Use:
trim() {
local orig="$1"
local trmd=""
while true;
do
trmd="${orig#[[:space:]]}"
trmd="${trmd%[[:space:]]}"
test "$trmd" = "$orig" && break
orig="$trmd"
done
printf -- '%s\n' "$trmd"
}
Unit test (for manual review):
#!/bin/bash
. trim.sh
enum() {
echo " a b c"
echo "a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a N b c "
echo "N a N b c "
echo " Na b c "
echo " a b c N "
echo " a b c N"
}
xcheck() {
local testln result
while IFS='' read testln;
do
testln=$(tr N '\n' <<<"$testln")
echo ": ~~~~~~~~~~~~~~~~~~~~~~~~~ :" >&2
result="$(trim "$testln")"
echo "testln='$testln'" >&2
echo "result='$result'" >&2
done
}
enum | xcheck
var=' a b c '
trimmed=$(echo $var)
There is a solution which only uses Bash built-ins called wildcards:
var=" abc "
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "===$var==="
Here's the same wrapped in a function:
trim() {
local var="$*"
# remove leading whitespace characters
var="${var#"${var%%[![:space:]]*}"}"
# remove trailing whitespace characters
var="${var%"${var##*[![:space:]]}"}"
printf '%s' "$var"
}
You pass the string to be trimmed in quoted form. e.g.:
trim " abc "
A nice thing about this solution is that it will work with any POSIX-compliant shell.
I've always done it with sed
var=`hg st -R "$path" | sed -e 's/ *$//'`
If there is a more elegant solution, I hope somebody posts it.
# Trim whitespace from both ends of specified parameter
trim () {
read -rd '' $1 <<<"${!1}"
}
# Unit test for trim()
test_trim () {
local foo="$1"
trim foo
test "$foo" = "$2"
}
test_trim hey hey &&
test_trim ' hey' hey &&
test_trim 'ho ' ho &&
test_trim 'hey ho' 'hey ho' &&
test_trim ' hey ho ' 'hey ho' &&
test_trim $'\n\n\t hey\n\t ho \t\n' $'hey\n\t ho' &&
test_trim $'\n' '' &&
test_trim '\n' '\n' &&
echo passed
From Bash Guide section on globbing
To use an extglob in a parameter expansion
#Turn on extended globbing
shopt -s extglob
#Trim leading and trailing whitespace from a variable
x=${x##+([[:space:]])}; x=${x%%+([[:space:]])}
#Turn off extended globbing
shopt -u extglob
Here's the same functionality wrapped in a function (NOTE: Need to quote input string passed to function):
trim() {
# Determine if 'extglob' is currently on.
local extglobWasOff=1
shopt extglob >/dev/null && extglobWasOff=0
(( extglobWasOff )) && shopt -s extglob # Turn 'extglob' on, if currently turned off.
# Trim leading and trailing whitespace
local var=$1
var=${var##+([[:space:]])}
var=${var%%+([[:space:]])}
(( extglobWasOff )) && shopt -u extglob # If 'extglob' was off before, turn it back off.
echo -n "$var" # Output trimmed string.
}
Usage:
string=" abc def ghi ";
#need to quote input-string to preserve internal white-space if any
trimmed=$(trim "$string");
echo "$trimmed";
If we alter the function to execute in a subshell, we don't have to worry about examining the current shell option for extglob, we can just set it without affecting the current shell. This simplifies the function tremendously. I also update the positional parameters "in place" so I don't even need a local variable
trim() {
shopt -s extglob
set -- "${1##+([[:space:]])}"
printf "%s" "${1%%+([[:space:]])}"
}
so:
$ s=$'\t\n \r\tfoo '
$ shopt -u extglob
$ shopt extglob
extglob off
$ printf ">%q<\n" "$s" "$(trim "$s")"
>$'\t\n \r\tfoo '<
>foo<
$ shopt extglob
extglob off
I created the following functions. I am not sure how portable printf is, but the beauty of this solution is you can specify exactly what is "white space" by adding more character codes.
iswhitespace()
{
n=`printf "%d\n" "'$1'"`
if (( $n != "13" )) && (( $n != "10" )) && (( $n != "32" )) && (( $n != "92" )) && (( $n != "110" )) && (( $n != "114" )); then
return 0
fi
return 1
}
trim()
{
i=0
str="$1"
while (( i < ${#1} ))
do
char=${1:$i:1}
iswhitespace "$char"
if [ "$?" -eq "0" ]; then
str="${str:$i}"
i=${#1}
fi
(( i += 1 ))
done
i=${#str}
while (( i > "0" ))
do
(( i -= 1 ))
char=${str:$i:1}
iswhitespace "$char"
if [ "$?" -eq "0" ]; then
(( i += 1 ))
str="${str:0:$i}"
i=0
fi
done
echo "$str"
}
#Call it like so
mystring=`trim "$mystring"`
I would simply use sed:
function trim
{
echo "$1" | sed -n '1h;1!H;${;g;s/^[ \t]*//g;s/[ \t]*$//g;p;}'
}
a) Example of usage on single-line string
string=' wordA wordB wordC wordD '
trimmed=$( trim "$string" )
echo "GIVEN STRING: |$string|"
echo "TRIMMED STRING: |$trimmed|"
Output:
GIVEN STRING: | wordA wordB wordC wordD |
TRIMMED STRING: |wordA wordB wordC wordD|
b) Example of usage on multi-line string
string=' wordA
>wordB<
wordC '
trimmed=$( trim "$string" )
echo -e "GIVEN STRING: |$string|\n"
echo "TRIMMED STRING: |$trimmed|"
Output:
GIVEN STRING: | wordAA
>wordB<
wordC |
TRIMMED STRING: |wordAA
>wordB<
wordC|
c) Final note:
If you don't like to use a function, for single-line string you can simply use a "easier to remember" command like:
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Example:
echo " wordA wordB wordC " | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Output:
wordA wordB wordC
Using the above on multi-line strings will work as well, but please note that it will cut any trailing/leading internal multiple space as well, as GuruM noticed in the comments
string=' wordAA
>four spaces before<
>one space before< '
echo "$string" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//'
Output:
wordAA
>four spaces before<
>one space before<
So if you do mind to keep those spaces, please use the function at the beginning of my answer!
d) EXPLANATION of the sed syntax "find and replace" on multi-line strings used inside the function trim:
sed -n '
# If the first line, copy the pattern to the hold buffer
1h
# If not the first line, then append the pattern to the hold buffer
1!H
# If the last line then ...
$ {
# Copy from the hold to the pattern buffer
g
# Do the search and replace
s/^[ \t]*//g
s/[ \t]*$//g
# print
p
}'
This is what I did and worked out perfect and so simple:
the_string=" test"
the_string=`echo $the_string`
echo "$the_string"
Output:
test
I needed to trim whitespace from a script when the IFS
variable was set to something else. Relying on Perl did the trick:
# trim() { echo $1; } # This doesn't seem to work, as it's affected by IFS
trim() { echo "$1" | perl -p -e 's/^\s+|\s+$//g'; }
strings="after --> , <-- before, <-- both --> "
OLD_IFS=$IFS
IFS=","
for str in ${strings}; do
str=$(trim "${str}")
echo "str= '${str}'"
done
IFS=$OLD_IFS
A simple answer is:
echo " lol " | xargs
Xargs will do the trimming for you. It's one command/program, no parameters, returns the trimmed string, easy as that!
Note: this doesn't remove all internal spaces so "foo bar"
stays the same; it does NOT become "foobar"
. However, multiple spaces will be condensed to single spaces, so "foo bar"
will become "foo bar"
. In addition it doesn't remove end of lines characters.
This is the simplest method I've seen. It only uses Bash, it's only a few lines, the regexp is simple, and it matches all forms of whitespace:
if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
test=${BASH_REMATCH[1]}
fi
Here is a sample script to test it with:
test=$(echo -e "\n \t Spaces and tabs and newlines be gone! \t \n ")
echo "Let's see if this works:"
echo
echo "----------"
echo -e "Testing:${test} :Tested" # Ugh!
echo "----------"
echo
echo "Ugh! Let's fix that..."
if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
test=${BASH_REMATCH[1]}
fi
echo
echo "----------"
echo -e "Testing:${test}:Tested" # "Testing:Spaces and tabs and newlines be gone!"
echo "----------"
echo
echo "Ah, much better."
In order to remove all the spaces from the beginning and the end of a string (including end of line characters):
echo $variable | xargs echo -n
This will remove duplicate spaces also:
echo " this string has a lot of spaces " | xargs echo -n
Produces: 'this string has a lot of spaces'
This is the simplest method I've seen. It only uses Bash, it's only a few lines, the regexp is simple, and it matches all forms of whitespace:
if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
test=${BASH_REMATCH[1]}
fi
Here is a sample script to test it with:
test=$(echo -e "\n \t Spaces and tabs and newlines be gone! \t \n ")
echo "Let's see if this works:"
echo
echo "----------"
echo -e "Testing:${test} :Tested" # Ugh!
echo "----------"
echo
echo "Ugh! Let's fix that..."
if [[ "$test" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
test=${BASH_REMATCH[1]}
fi
echo
echo "----------"
echo -e "Testing:${test}:Tested" # "Testing:Spaces and tabs and newlines be gone!"
echo "----------"
echo
echo "Ah, much better."
This trims multiple spaces of the front and end
whatever=${whatever%% *}
whatever=${whatever#* }
You can use old-school tr
. For example, this returns the number of modified files in a git repository, whitespaces stripped.
MYVAR=`git ls-files -m|wc -l|tr -d ' '`
Use:
trim() {
local orig="$1"
local trmd=""
while true;
do
trmd="${orig#[[:space:]]}"
trmd="${trmd%[[:space:]]}"
test "$trmd" = "$orig" && break
orig="$trmd"
done
printf -- '%s\n' "$trmd"
}
Unit test (for manual review):
#!/bin/bash
. trim.sh
enum() {
echo " a b c"
echo "a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a b c "
echo " a N b c "
echo "N a N b c "
echo " Na b c "
echo " a b c N "
echo " a b c N"
}
xcheck() {
local testln result
while IFS='' read testln;
do
testln=$(tr N '\n' <<<"$testln")
echo ": ~~~~~~~~~~~~~~~~~~~~~~~~~ :" >&2
result="$(trim "$testln")"
echo "testln='$testln'" >&2
echo "result='$result'" >&2
done
}
enum | xcheck
I needed to trim whitespace from a script when the IFS
variable was set to something else. Relying on Perl did the trick:
# trim() { echo $1; } # This doesn't seem to work, as it's affected by IFS
trim() { echo "$1" | perl -p -e 's/^\s+|\s+$//g'; }
strings="after --> , <-- before, <-- both --> "
OLD_IFS=$IFS
IFS=","
for str in ${strings}; do
str=$(trim "${str}")
echo "str= '${str}'"
done
IFS=$OLD_IFS
Python has a function strip()
that works identically to PHP's trim()
, so we can just do a little inline Python to make an easily understandable utility for this:
alias trim='python -c "import sys; sys.stdout.write(sys.stdin.read().strip())"'
This will trim leading and trailing whitespace (including newlines).
$ x=`echo -e "\n\t \n" | trim`
$ if [ -z "$x" ]; then echo hi; fi
hi
This trims multiple spaces of the front and end
whatever=${whatever%% *}
whatever=${whatever#* }
# Strip leading and trailing white space (new line inclusive).
trim(){
[[ "$1" =~ [^[:space:]](.*[^[:space:]])? ]]
printf "%s" "$BASH_REMATCH"
}
OR
# Strip leading white space (new line inclusive).
ltrim(){
[[ "$1" =~ [^[:space:]].* ]]
printf "%s" "$BASH_REMATCH"
}
# Strip trailing white space (new line inclusive).
rtrim(){
[[ "$1" =~ .*[^[:space:]] ]]
printf "%s" "$BASH_REMATCH"
}
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "$(rtrim "$(ltrim "$1")")"
}
OR
# Strip leading and trailing specified characters. ex: str=$(trim "$str" $'\n a')
trim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
printf "%s" "${BASH_REMATCH[1]}"
}
OR
# Strip leading specified characters. ex: str=$(ltrim "$str" $'\n a')
ltrim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^["$trim_chrs"]*(.*[^"$trim_chrs"]) ]]
printf "%s" "${BASH_REMATCH[1]}"
}
# Strip trailing specified characters. ex: str=$(rtrim "$str" $'\n a')
rtrim(){
if [ "$2" ]; then
trim_chrs="$2"
else
trim_chrs="[:space:]"
fi
[[ "$1" =~ ^(.*[^"$trim_chrs"])["$trim_chrs"]*$ ]]
printf "%s" "${BASH_REMATCH[1]}"
}
# Strip leading and trailing specified characters. ex: str=$(trim "$str" $'\n a')
trim(){
printf "%s" "$(rtrim "$(ltrim "$1" "$2")" "$2")"
}
OR
Building upon moskit's expr soulution...
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)[[:space:]]*$"`"
}
OR
# Strip leading white space (new line inclusive).
ltrim(){
printf "%s" "`expr "$1" : "^[[:space:]]*\(.*[^[:space:]]\)"`"
}
# Strip trailing white space (new line inclusive).
rtrim(){
printf "%s" "`expr "$1" : "^\(.*[^[:space:]]\)[[:space:]]*$"`"
}
# Strip leading and trailing white space (new line inclusive).
trim(){
printf "%s" "$(rtrim "$(ltrim "$1")")"
}
Use AWK:
echo $var | awk '{gsub(/^ +| +$/,"")}1'
While it's not strictly Bash this will do what you want and more:
php -r '$x = trim(" hi there "); echo $x;'
If you want to make it lowercase too, do:
php -r '$x = trim(" Hi There "); $x = strtolower($x) ; echo $x;'
You can delete newlines with tr
:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done
While it's not strictly Bash this will do what you want and more:
php -r '$x = trim(" hi there "); echo $x;'
If you want to make it lowercase too, do:
php -r '$x = trim(" Hi There "); $x = strtolower($x) ; echo $x;'
var=' a b c '
trimmed=$(echo $var)
I've seen scripts just use variable assignment to do the job:
$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar
Whitespace is automatically coalesced and trimmed. One has to be careful of shell metacharacters (potential injection risk).
I would also recommend always double-quoting variable substitutions in shell conditionals:
if [ -n "$var" ]; then
since something like a -o or other content in the variable could amend your test arguments.
To remove spaces and tabs from left to first word, enter:
echo " This is a test" | sed "s/^[ \t]*//"
cyberciti.biz/tips/delete-leading-spaces-from-front-of-each-word.html
I've seen scripts just use variable assignment to do the job:
$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar
Whitespace is automatically coalesced and trimmed. One has to be careful of shell metacharacters (potential injection risk).
I would also recommend always double-quoting variable substitutions in shell conditionals:
if [ -n "$var" ]; then
since something like a -o or other content in the variable could amend your test arguments.
Here's a trim() function that trims and normalizes whitespace
#!/bin/bash
function trim {
echo $*
}
echo "'$(trim " one two three ")'"
# 'one two three'
And another variant that uses regular expressions.
#!/bin/bash
function trim {
local trimmed="$@"
if [[ "$trimmed" =~ " *([^ ].*[^ ]) *" ]]
then
trimmed=${BASH_REMATCH[1]}
fi
echo "$trimmed"
}
echo "'$(trim " one two three ")'"
# 'one two three'
This worked for me:
text=" trim my edges "
trimmed=$text
trimmed=${trimmed##+( )} #Remove longest matching series of spaces from the front
trimmed=${trimmed%%+( )} #Remove longest matching series of spaces from the back
echo "<$trimmed>" #Adding angle braces just to make it easier to confirm that all spaces are removed
#Result
<trim my edges>
To put that on fewer lines for the same result:
text=" trim my edges "
trimmed=${${text##+( )}%%+( )}
There are a lot of answers, but I still believe my just-written script is worth being mentioned because:
"$*"
joins multiple arguments using one space. if you want to trim & output only the first argument, use "$1"
insteadThe script:
trim() {
local s2 s="$*"
until s2="${s#[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
until s2="${s%[[:space:]]}"; [ "$s2" = "$s" ]; do s="$s2"; done
echo "$s"
}
Usage:
mystring=" here is
something "
mystring=$(trim "$mystring")
echo ">$mystring<"
Output:
>here is
something<
You can delete newlines with tr
:
var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
echo $var
done
Source: Stackoverflow.com