Listing files with pattern with starting and ending

ls

I want to list all files in a directory that start with 'abc' and end with '.zip'

I'm trying to use ls.

The directory has a lot of zip files starting with abc<date> and xvz<date>.
I only want to get the list of the abc<date>.zip

Best Answer

ls doesn't do pattern matching on file names. It just lists the content of the directories and the files it is being given as arguments.

Your shell on the other hand has a feature called globbing or filename generation that expands a pattern into a list of files matching that pattern.

Here that glob pattern would be abc*.zip (* being a wildcard that stands for any number of characters).

You'd pass it to any command you like such as printf for printing:

printf '%s\n' abc*.zip

You could also pass it to ls -l to display the attributes of those files:

ls -ld abc*.zip

(we need -d because if any of those files are of type directory, ls would list their content otherwise).

Or to unzip to extract them if only unzip could extract more than one file at a time. Unfortunately it doesn't, so you'd need either to use xargs -n1 or a for loop:

printf '%s\0' abc*.zip | xargs -r0n1 unzip

Or:

for file in abc*.zip; do unzip "$file"; done

But in fact, unzip being more like a port of a MS-DOS command, unzip itself would treat its argument as a glob. In other words, unzip 'abc*.zip' will not unzip the file called abc*.zip (a perfectly valid file name on Unix, not on Microsoft operating systems), but the files matching the abc*.zip pattern, so you'd actually want:

 unzip 'abc*.zip'

(Actually our xargs and for approach above would be wrong, because if there's a file called abc*.zip for instance, unzip would treat it as a pattern! See bsdtar for a more unixy way to extract zip archives)


For case insensitive matching, you'd use [aA][bB][cC]*.[zZ][iI][pP] portably. Some shells have extended globbing operators for case insensitive matching:

  • zsh:

    setopt extendedglob
    ls -ld (#i)abc*.zip
    

    Or:

    ls -ld ((#i)abc)*.zip
    

    if you only want the abc part to be case insensitive.

  • ksh93:

    ls -ld ~(i)abc*.zip
    

    or:

    ls -ld ~(i:abc)*.zip
    
  • with bash.

    shopt -s nocaseglob
    ls -ld abc*.zip
    

    (no way to have only parts of the globs case sensitive there other than by using the portable syntax).

  • with yash:

    set +o case-glob
    ls -ld abc*.zip
    

    same remark as for bash above.

Related Question