Shell Script Special Character Test

For discussions about programming and projects not necessarily associated with Porteus.

Shell Script Special Character Test

Postby Bogomips » 27 Nov 2014, 02: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, 02: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
Full of knowledge
Full of knowledge
 
Posts: 2291
Joined: 25 Jun 2014, 16:21
Location: London
Distribution: 3.2.2 Cinnamon & KDE5

Re: Shell Script Special Character Test

Postby brokenman » 27 Nov 2014, 02: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
Site Admin
Site Admin
 
Posts: 5362
Joined: 27 Dec 2010, 04:50
Location: Brazil
Distribution: Porteus v3.2rcX all desktops

Re: Shell Script Special Character Test

Postby Bogomips » 29 Nov 2014, 21: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
        :good:
      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
      Full of knowledge
      Full of knowledge
       
      Posts: 2291
      Joined: 25 Jun 2014, 16:21
      Location: London
      Distribution: 3.2.2 Cinnamon & KDE5

      Re: Shell Script Special Character Test

      Postby brokenman » 01 Dec 2014, 10: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
      Site Admin
      Site Admin
       
      Posts: 5362
      Joined: 27 Dec 2010, 04:50
      Location: Brazil
      Distribution: Porteus v3.2rcX all desktops

      Re: Shell Script Special Character Test

      Postby Bogomips » 27 Dec 2014, 02: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
                Full of knowledge
                Full of knowledge
                 
                Posts: 2291
                Joined: 25 Jun 2014, 16:21
                Location: London
                Distribution: 3.2.2 Cinnamon & KDE5


                Return to Programming



                Who is online

                Users browsing this forum: No registered users and 1 guest