views:

24612

answers:

15

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.

  • Is there a simple way to strip whitespace from $var (like trim() in php)?

or

  • Is there a standard way of dealing with this issue?

I could use sed or awk, but I'd like to think there is a more elegant solution to this problem.

+4  A: 

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.

Paul Tomblin
+7  A: 

Bash has regular expressions, but they're well-hidden:

$ var='abc def'
$ echo $var
abc def
$ echo ${var/ /}
abcdef
Ant P.
It doesn't seem to work with cygwin.
Paul Tomblin
Or rather, it works for spaces in the middle of a var, but not when I attempt to anchor it at the end.
Paul Tomblin
Does this help any? From the manpage: "${parameter/pattern/string} [...] If pattern begins with %, it must match at the end of the expanded value of parameter."
Ant P.
@Ant, so they're not really regular expressions, but something similar?
Paul Tomblin
They're regex, just a strange dialect.
Ant P.
to replace all matches echo ${var// }
Peter Lindqvist
+3  A: 

You can delete newlines with tr:

var=`hg st -R "$path" | tr -d '\n'`
if [ -n $var ]; then
    echo $var
done
Adam Rosenfield
I don't want to remove '\n' from the middle of the string, only from the beginning or end.
too much php
+3  A: 

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.

MikeC
A: 

Sorry everyone, there was a problem elsewhere in my script and I thought that var had a trailing newline in it, but that actually was not the case. Command substitution strips trailing newlines automatically, as mentioned here: http://tldp.org/LDP/abs/html/commandsub.html.

too much php
it doesn't strip preceding whitespace, however
rogerdpack
+4  A: 
#!/bin/sh

trim()
{
    trimmed=$1
    trimmed=${trimmed%% }
    trimmed=${trimmed## }

    echo $trimmed
}


HELLO_WORLD=$(trim "hello world  ")
FOO_BAR=$(trim " foo bar")
BOTH_SIDES=$(trim " both sides  ")
echo "'${HELLO_WORLD}', '${FOO_BAR}', '${BOTH_SIDES}'"
Brian Cain
That will only trim a single leading or trailing space.
Insyte
+2  A: 

use awk

echo $var | awk '{gsub(/^ +| +$/,"")}1'
ghostdog74
Sweet that seems to work (ex:)`$stripped_version=`echo $var | awk '{gsub(/^ +| +$/,"")}1'``
rogerdpack
+8  A: 
#!/bin/sh

trim() { echo $1; }

echo ">>$(trim 'right side    ')<<"
echo ">>$(trim '    left side')<<"
echo ">>$(trim '    both sides    ')<<"
Francis Litterio
+1  A: 

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 ' '`
pojo
+1  A: 

(Note: just created an account, don't have enough reputation to comment, thus a new answer)

In response to Brian Cain's answer and Insyte's comment:

With bash's extended pattern matching features enabled (shopt -s extglob), you can use this:

{trimmed##*( )}

to remove an arbitrary amount of leading spaces.

Mooshu
A: 

Removing spaces to one space:

(text) | fmt -su

gardziol
+1  A: 

This will remove all spaces ...

echo " test test test " | tr -d ' '

so this results in

testtesttest

This will remove trailing spaces...

echo " test test test " | sed 's/ *$//g'

which results in

 test test test

This will remove leading spaces...

echo " test test test " | sed 's/^ *//g'

which results in

test test test
MattyV
+1  A: 
# "Remove leading & trailing whitespace from a Bash variable",
# http://codesnippets.joyent.com/posts/show/1816

var="    abc    "
var="${var#"${var%%[![:space:]]*}"}"   # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}"   # remove trailing whitespace characters
echo "$var"
bashfu
+1  A: 

assignments ignore leading and trailing whitespace and as such can be used to trim

$ var=`echo '   hello'`; echo $var
hello
evanx
A: 

This trims multiple spaces of the front and end

whatever=${whatever%% *}

whatever=${whatever#* }

gretelmk2