I want to list (or delete, or do some other operation) on certain files in a directory, like this:

$ ls /opt/somedir/
aa  bb  cc  aa.txt  bb.txt  cc.txt
$ ls /opt/somedir/(aa|bb|cc)  ## pseudo-bash :p
aa  bb  cc

How can I achieve this (without cd-ing to the directory first)?


Use curly braces for it:

ls /opt/somedir/{aa,bb,cc}

For more information read about brace expansion.


Under bash, run shopt -s extglob (or put it in your ~/.bashrc), and you can use additional patterns that provide regular expressions with an unusual syntax (inherited from ksh). You can use these patterns in ksh too, of course, and also in zsh after setopt ksh_glob.

$ shopt -s extglob
$ ls /opt/somedir/@(aa|bb|cc|doesnotexist)
/opt/somedir/aa   /opt/somedir/bb  /opt/somedir/cc

In zsh, you can directly use (foo|bar) as a pattern.

% ls /opt/somedir/(aa|bb|cc|doesnotexist)
/opt/somedir/aa   /opt/somedir/bb  /opt/somedir/cc

Note that the command is called with the full path. If you want to call the command with a short path, you'll need to change the directory somehow, and (cd /opt/somedir && somecommand aa bb cc) is by far the easiest way.

  • If you look closely, you'll see that I specify "without cd-ing to the directory first" in my question ;) – neu242 Dec 30 '11 at 10:10

You can filter using egrep:

ls | egrep '(aa|bb|cc)'

To find all text files:

ls | egrep '(aa|bb|cc).txt'
  • 1
    dot will match every character, and this approach make it difficult to further operate on these files – enzotib Dec 29 '11 at 12:22
  • 1
    I got the feeling that ls was just an example command, too. – Random832 Dec 29 '11 at 14:23
  • Yup, you're right, I specified that I want to do perform an operation: listing files was just an example. – neu242 Dec 30 '11 at 10:15
  • Good comments dear friends, thanks. Good luck neu242 :D – Ocean Dec 31 '11 at 16:52

First, I direct you to: never parse ls, ever. The proper, and canonical way to do what you want is with find.

For example:

find /opt/somedir -regex '.*[aa|bb|cc].*' -exec mv '{}' ~/backup \;

I usually use -name instead of -regex as it is simpler. But a regex fits your use case. You should run the command without -exec the first time, to make sure they actually are the files you want moved/deleted.

  • I never said I'd parse ls, and Rush had a far better answer. Thanks for trying, though :) – neu242 Dec 29 '11 at 22:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.