Home > Net >  Why are two form of expanding list using @ not providing same results?
Why are two form of expanding list using @ not providing same results?

Time:10-30

In trying to answer this question, I came up with this solution, which works:

#!/bin/bash

testor=$(shopt | grep extglob | awk '{ print $2 }' )

if [ "${testor}" = "off" ]
then
    shopt -s extglob
    shopt | grep extglob
fi

ls ./WORKS/@(*.sh|*.dat|*.txt)  

and the output is this:

ericthered@OasisMega1:/0__WORK$ ./junk_37.sh
extglob         on
./WORKS/abc_junk_def.txt        ./WORKS/junk_007.sh  ./WORKS/junk_28.sh
./WORKS/assignListToBashArray.sh    ./WORKS/junk_008.sh  ./WORKS/junk_28.txt
./WORKS/awkEmbeddedFunction.sh      ./WORKS/junk_009.sh  ./WORKS/junk_29.dat
./WORKS/droneConnectWiFi.sh     ./WORKS/junk_010.sh  ./WORKS/junk_29.sh
./WORKS/expandNumericDirectories.sh ./WORKS/junk_011.sh  ./WORKS/junk_30.sh
./WORKS/findMatchOnEmbeddedFilename.sh  ./WORKS/junk_012.sh  ./WORKS/junk_31.sh
./WORKS/junk_001.sh         ./WORKS/junk_013.sh  ./WORKS/musicplayer.sh
./WORKS/junk_002.sh         ./WORKS/junk_014.sh  ./WORKS/prototypeEditorWrapper.sh
./WORKS/junk_003.sh         ./WORKS/junk_015.sh  ./WORKS/prototypeSendmailWrapper.sh
./WORKS/junk_004.sh         ./WORKS/junk_26.dat  ./WORKS/reportNotLowercase.sh
./WORKS/junk_005.sh         ./WORKS/junk_26.sh
ericthered@OasisMega1:/0__WORK$ 

But ... if instead, I use the following line,

ls @(./WORKS/*.sh|./WORKS/*.dat|./WORKS/*.txt)

it reports this error:

ls: cannot access '@(./WORKS/*.sh|./WORKS/*.dat|./WORKS/*.txt)': No such file or directory

I would appreciate someone providing insights as to why the two forms are not equivalent.

CodePudding user response:

Converting my earlier comment to answer so that solution is easy to find for future visitors.

A pattern in extglob doesn't work with / so:

cd WORKKS

# reason of failure, presence of / in glob pattern
ls @(./junk_001.sh)
No such file or directory

# this will work fine with omission of /
ls @(junk_001.sh)
junk_001.sh

A workaround fix for your problem using extglob:

(cd WORKS; ls @(*.sh|*.dat|*.txt))

# or use find with regex
find WORKS -regextype awk -regex '.*/[^.]*\.(sh|dat|txt)$'

CodePudding user response:

As per POSIX, directory separators has to be matched explicitly in filename expansion; *, ?, [...], etc. do not match them. The following doesn't work either for the same reason.

$ ls ./WORKS[/]*.sh
ls: cannot access './WORKS[/]*.sh': No such file or directory
$ ls ./WORKS*.sh
ls: cannot access './WORKS*.sh': No such file or directory
  • Related