For discussions about programming and projects not necessarily associated with Porteus.
-
Bogomips
- Full of knowledge

- Posts: 2564
- Joined: 25 Jun 2014, 15:21
- Distribution: 3.2.2 Cinnamon & KDE5
- Location: London
Post#1
by Bogomips » 27 Nov 2014, 01:15
Quick way of testing if string ends in '*'.
Unsuccessful Efforts without Quoting
Code: Select all
#set -x
echo $1
s=$1A
if [ "${s##*\*}" = "A" ]; then echo $1 "Ends in *"; exit; fi
echo $1 No Match
guest@porteus:~$ touch abcd abce
guest@porteus:~$ ls abc*
abcd abce
guest@porteus:~$ sh p10/Por/ast.sh abc*
abcd
abcd No Match
guest@porteus:~$ rm abc*
guest@porteus:~$ sh p10/Por/ast.sh abc*
abc*
abc* Ends in *
set -x
echo $1
s=$1A
if [ "${s##*\*}" = "A" ]; then echo $1 "Ends in *"; exit; fi
echo $1 No Match
guest@porteus:~$ touch abcd abce
guest@porteus:~$ ls abc*
abcd abce
guest@porteus:~$ sh p10/Por/ast.sh abc*
+ echo abcd
abcd
+ s=abcdA
+ '[' abcdA = A ']'
+ echo abcd No Match
abcd No Match
guest@porteus:~$ rm abc*
guest@porteus:~$ sh p10/Por/ast.sh abc*
+ echo 'abc*'
abc*
+ s='abc*A'
+ '[' A = A ']'
+ echo 'abc*' 'Ends in *'
abc* Ends in *
+ exit
Code: Select all
guest@porteus:~$ touch abcd abce
guest@porteus:~$ ls abc*
abcd abce
guest@porteus:~$ sh p10/Por/ast.sh "abc*"
abcd abce
abcd abce Ends in *
guest@porteus:~$ sh p10/Por/ast.sh 'abc*'
abcd abce
abcd abce Ends in *
Last edited by
Bogomips on 27 Nov 2014, 01:38, edited 1 time in total.
Linux porteus 4.4.0-porteus #3 SMP PREEMPT Sat Jan 23 07:01:55 UTC 2016 i686 AMD Sempron(tm) 140 Processor AuthenticAMD GNU/Linux
NVIDIA Corporation C61 [GeForce 6150SE nForce 430] (rev a2) MemTotal: 901760 kB MemFree: 66752 kB
Bogomips
-
brokenman
- Site Admin

- Posts: 6105
- Joined: 27 Dec 2010, 03:50
- Distribution: Porteus v4 all desktops
- Location: Brazil
Post#2
by brokenman » 27 Nov 2014, 01:34
x="abcd*"
[[ `echo $x | awk '{print substr($0,length,1)}'` = "*" ]] && echo yes
[[ `echo $x | awk '$0=$NF' FS=` = "*" ]] && echo yes
[[ "${x: -1}" = "*" ]] && echo yes
How do i become super user?
Wear your underpants on the outside and put on a cape.
brokenman
-
Bogomips
- Full of knowledge

- Posts: 2564
- Joined: 25 Jun 2014, 15:21
- Distribution: 3.2.2 Cinnamon & KDE5
- Location: London
Post#3
by Bogomips » 29 Nov 2014, 20:09
brokenman wrote:x="abcd*"
[[ `echo $x | awk '{print substr($0,length,1)}'` = "*" ]] && echo yes
[[ `echo $x | awk '$0=$NF' FS=` = "*" ]] && echo yes
[[ "${x: -1}" = "*" ]] && echo yes
Thanks for input.
Code: Select all
guest@porteus:~$ touch abc* abc*xyz* abcde abcef awxybcz axyzbc
guest@porteus:~$ ls a*
abc* abc*xyz* abcde abcef awxybcz axyzbc
- [[ `echo $x | awk '{print substr($0,length,1)}'` = "*" ]] && echo yes Doesn't work.
Code: Select all
guest@porteus:~$ x=tuv*
guest@porteus:~$ [[ `echo $x | awk '{print substr($0,length,1)}'` = "*" ]] && echo yes || echo no
yes
guest@porteus:~$ x=abc*f*
guest@porteus:~$ [[ `echo $x | awk '{print substr($0,length,1)}'` = "*" ]] && echo yes || echo no
no
- [[ `echo $x | awk '$0=$NF' FS=` = "*" ]] && echo yes
No idea how this is supposed to function. Doesn't work.Code: Select all
guest@porteus:~$ x=tuv*
guest@porteus:~$ [[ `echo $x | awk '$0=$NF' FS=` = "*" ]] && echo yes || echo no
yes
guest@porteus:~$ x=abc*f*
guest@porteus:~$ [[ `echo $x | awk '$0=$NF' FS=` = "*" ]] && echo yes || echo no
no
- [[ "${x: -1}" = "*" ]] && echo yes Simplest Works.
Code: Select all
guest@porteus:~$ x=tuv*
guest@porteus:~$ [[ "${x: -1}" = "*" ]] && echo yes || echo no
yes
guest@porteus:~$ x=abc*f*
guest@porteus:~$ [[ "${x: -1}" = "*" ]] && echo yes || echo no
yes
guest@porteus:~$ x=abc*
guest@porteus:~$ [[ "${x: -1}" = "*" ]] && echo yes || echo no
yes
guest@porteus:~$ x=abc*ef
guest@porteus:~$ [[ "${x: -1}" = "*" ]] && echo yes || echo no
no
guest@porteus:~$ x=abc
guest@porteus:~$ [[ "${x: -1}" = "*" ]] && echo yes || echo no
no
guest@porteus:~$ x=ab*d*e
guest@porteus:~$ [[ "${x: -1}" = "*" ]] && echo yes || echo no
no

Linux porteus 4.4.0-porteus #3 SMP PREEMPT Sat Jan 23 07:01:55 UTC 2016 i686 AMD Sempron(tm) 140 Processor AuthenticAMD GNU/Linux
NVIDIA Corporation C61 [GeForce 6150SE nForce 430] (rev a2) MemTotal: 901760 kB MemFree: 66752 kB
Bogomips
-
brokenman
- Site Admin

- Posts: 6105
- Joined: 27 Dec 2010, 03:50
- Distribution: Porteus v4 all desktops
- Location: Brazil
Post#4
by brokenman » 01 Dec 2014, 09:22
There are other variations where some of these won't work too, but in your example you give only one special character on the end and don't stipulate any conditions.
How do i become super user?
Wear your underpants on the outside and put on a cape.
brokenman
-
Bogomips
- Full of knowledge

- Posts: 2564
- Joined: 25 Jun 2014, 15:21
- Distribution: 3.2.2 Cinnamon & KDE5
- Location: London
Post#5
by Bogomips » 27 Dec 2014, 01:23
brokenman wrote:There are other variations where some of these won't work too, but in your example you give only one special character on the end and don't stipulate any conditions.
Not stipulating any conditions, had the added benefit of improving my understanding of what's going on here.
Stipulating condition: x is argument to shell script
ast.sh, and may or may not be a wildcard argument, which has to be detected.
Code: Select all
[[ "${1: -1}" = "*" ]] && echo yes || echo no
Code: Select all
guest@porteus:~$ sh ast.sh tuv*
yes
guest@porteus:~$ sh ast.sh abc*f*
no
guest@porteus:~$ sh ast.sh abc*
yes
guest@porteus:~$ sh ast.sh abc*ef
no
guest@porteus:~$ sh ast.sh abc
no
guest@porteus:~$ sh ast.sh ab*d*e
no
guest@porteus:~$ sh ast.sh ab*
yes
guest@porteus:~$ sh ast.sh abcd*
no
guest@porteus:~$ sh ast.sh a*
yes
guest@porteus:~$ sh ast.sh a*y*
yes
guest@porteus:~$ sh ast.sh aw*
no
guest@porteus:~$ sh ast.sh ax*
no
- The four instances where script fails to come up to expectation, can be tweaked by enclosing argument in quotes, which presumably inhibits pathname expansion.
Code: Select all
guest@porteus:~$ sh ast.sh "abc*f*"
yes
guest@porteus:~$ sh ast.sh "abcd*"
yes
guest@porteus:~$ sh ast.sh "aw*"
yes
guest@porteus:~$ sh ast.sh "ax*"
yes
- Final condition to stipulate, is that wildcard argument not be quoted. In this case the shell script has no control, as it is the shell, in which script is run, which decides wildcard substitution:
Code: Select all
guest@porteus:~$ touch abc* abc*xyz* abcde abcef awxybcz axyzbc
guest@porteus:~$ touch abcgh
guest@porteus:~$ touch abc*ij
guest@porteus:~$ ls a*
abc* abc*ij abc*xyz* abcde abcef abcgh awxybcz axyzbc
guest@porteus:~$ sh ast.sh abc*
yes
guest@porteus:~$ set -f #Disable pathname expansion.
guest@porteus:~$ ls a*
/bin/ls: cannot access a*: No such file or directory
guest@porteus:~$ sh ast.sh abc*
yes
guest@porteus:~$ sh ast.sh abc*f*
yes
guest@porteus:~$ sh ast.sh abcd*
yes
guest@porteus:~$ sh ast.sh aw*
yes
guest@porteus:~$ sh ast.sh ax*
yes
However, there is no point in disallowing pathname expansion as it defeats the whole purpose of the exercise. - The argument abc* could always be detected, because the file abc* was always the first parameter following pathname expansion.
Code: Select all
guest@porteus:~$ rm abc*
guest@porteus:~$ set +f #Using + rather than - causes option to be turned off.
guest@porteus:~$ ls a*
abc*ij abc*xyz* abcde abcef abcgh ast.sh awxybcz axyzbc
guest@porteus:~$ sh ast.sh abc*
no
guest@porteus:~$ ls abc*
abc*ij abc*xyz* abcde abcef abcgh
With the file abc*ij as first parameter following pathname expansion, the argument abc* cannot be deduced to have a wildcard termination. - Looking at this next case, am not able to work out $@ (unquoted expansion of @) in second instance:
Code: Select all
ast.sh
#set -x
#set -f
[[ "${1: -1}" = "*" ]] && echo yes || echo no
echo '$1='"$1"
echo '$#='$#
echo Positional Parameters '$@': $@
echo Positional Parameters '"$@"': "$@"
echo $@ | awk '{print "Positional Params $@ (awk): "$0}'
______________________________________________________________________________
guest@porteus:~$ touch abc*ij abc*xyz* abcde abcef abcgh
guest@porteus:~$ ls a*
abc*ij abc*xyz* abcde abcef abcgh ast.sh
guest@porteus:~$ sh ast.sh abc*
no
$1=abc*ij
$#=5
Positional Parameters $@: abc*ij abc*xyz* abcde abcef abcgh
Positional Parameters "$@": abc*ij abc*xyz* abcde abcef abcgh
Positional Params $@ (awk): abc*ij abc*xyz* abcde abcef abcgh
guest@porteus:~$ set -f
guest@porteus:~$ touch abc*
guest@porteus:~$ ls a*
/bin/ls: cannot access a*: No such file or directory
guest@porteus:~$ set +f
guest@porteus:~$ ls a*
abc* abc*ij abc*xyz* abcde abcef abcgh ast.sh
guest@porteus:~$ sh ast.sh abc*
yes
$1=abc*
$#=6
Positional Parameters $@: abc* abc*ij abc*xyz* abcde abcef abcgh abc*ij abc*xyz* abcde abcef abcgh
Positional Parameters "$@": abc* abc*ij abc*xyz* abcde abcef abcgh
Positional Params $@ (awk): abc* abc*ij abc*xyz* abcde abcef abcgh abc*ij abc*xyz* abcde abcef abcgh
In conclusion, under the condition that the script is always invoked with one argument, it is safe to say that there is a wildcard in the argument, should the number of positional parameters "$#" exceed one. However with just one possitional parameter it looks like there is no way of telling if this is resulting from a wildcard in the argument or from the argument proper.
Linux porteus 4.4.0-porteus #3 SMP PREEMPT Sat Jan 23 07:01:55 UTC 2016 i686 AMD Sempron(tm) 140 Processor AuthenticAMD GNU/Linux
NVIDIA Corporation C61 [GeForce 6150SE nForce 430] (rev a2) MemTotal: 901760 kB MemFree: 66752 kB
Bogomips