i would be thankfull if you could help me how to figure out, how to determine if a variable's content starts with the hash sign:
#!bin/sh
myvar="#comment asfasfasdf"
if [ myvar = #* ]
this does not work.
Thanks!
Jans
Your original approach would work just fine if you escaped the hash:
$ [[ '#snort' == \#* ]]; echo $?
0
Another approach would be slicing off the first character of the variable's content, using "Substring Expansion":
if [[ ${x:0:1} == '#' ]]
then
echo 'yep'
else
echo 'nope'
fi
yep
From the Bash man page:
${parameter:offset}
${parameter:offset:length}
Substring Expansion. Expands to up to length characters of
parameter starting at the character specified by offset. If
length is omitted, expands to the substring of parameter start-
ing at the character specified by offset. length and offset are
arithmetic expressions (see ARITHMETIC EVALUATION below).
length must evaluate to a number greater than or equal to zero.
If offset evaluates to a number less than zero, the value is
used as an offset from the end of the value of parameter. If
parameter is @, the result is length positional parameters
beginning at offset. If parameter is an array name indexed by @
or *, the result is the length members of the array beginning
with ${parameter[offset]}. A negative offset is taken relative
to one greater than the maximum index of the specified array.
Note that a negative offset must be separated from the colon by
at least one space to avoid being confused with the :- expan-
sion. Substring indexing is zero-based unless the positional
parameters are used, in which case the indexing starts at 1.
POSIX-compatible version:
[ "${var%${var#?}}"x = '#x' ] && echo yes
or:
[ "${var#\#}"x != "${var}x" ] && echo yes
or:
case "$var" in
\#*) echo yes ;;
*) echo no ;;
esac
case
method seems to be the fastest of the three on a fairly old 32-bit x86 computer. All three are far more efficient than a simple example which pipes to a forked stdin processor like: echo $var | cut -c1
. My analysis was quite basic based on 10,000,000 iterations on just one computer/os - YMMV. I just used that slower computer to exaggerate any differences and make them more visible - at least on that one platform.
cut
flavor took 5+ hours.
case
runs faster than parameter expansions. Any clues?
I know this may be heresy, but for this kind of things I'd rather use grep or egrep rather than doing it from within the shell. It's a little more costly (I guess) but for me this solution's readability offsets that. It's a matter of personal taste though, of course.
So:
myvar=" #comment asfasfasdf"
if ! echo $myvar | egrep -q '^ *#'
then
echo "not a comment"
else
echo "commented out"
fi
It works with or without leading spaces. If you'd like to account for leading tabs also, use egrep -q '^[ \t]*#' instead.
Here is another way...
# assign to var the value of argument actual invocation
var=${1-"#default string"}
if [[ "$var" == "#"* ]]
then
echo "$var starts with a #"
fi
Just copy paste the content to a file, grant execution permissions, and watch how it just works ;).
Hope it helps!
Greetings.
bash
solution, maybe you could edit your question, as it implies you're wishing for ash
/dash
solution.#!
line as a relative path in that line is apparently taken relative to the current directory of the process executing the script rather than relative to where the script is located.