2

I have a folder A. Inside the folder, there are some files a,b,c,d and there is a subfolder, B, containing files e,f,g.

Suppose I want to open files a,b,c,d: then I just type xdg-open *. However, this also goes into subfolder B and opens e,f,g as well. What's the easiest way to open just a,b,c,d?

EDIT: what I really mean with the question is how to open all files in a folder, but not those contained in any subfolders.

1
  • See my updated answer, extended globbing is what you're looking for.
    – slm
    Nov 16, 2013 at 1:29

3 Answers 3

4

How about find A -maxdepth 1 -type f -exec xdg-open {} \;

That should open all files in folder A without going any further than the top level.

6
  • That'll work, but it's a pretty long command. I could alias it, but I feel as if a more elegant solution has to be possible...
    – Newb
    Nov 15, 2013 at 22:41
  • As far as I'm aware that's the closest your gonna get to what you need.
    – Jeight
    Nov 15, 2013 at 23:03
  • This seems like the best option.
    – coteyr
    Nov 16, 2013 at 0:58
  • @coteyr - You can do better than this using extended globbing in Bash! See my updated answer.
    – slm
    Nov 16, 2013 at 1:28
  • @slm, I think the globbing is nice but it seems to be "harder" to use unless you want to "know" the folders content. This answer can just be run with out any special knowledge of the directory.
    – coteyr
    Nov 16, 2013 at 4:59
1

Method #1 - Shell expansions

If you know that the items you're after are sequentially named you can use shell expansions in a variety of ways.

Examples

$ xdg-open [a-d]
$ xdg-open {a..d}
$ xdg-open a* b*

Method #2 - Extended globbing

In Bash (versions 3.2+) you can use extended globbing to included everything except something, which I believe is what you're asking for.

Examples

$ xdg-open !(B)
$ xdg-open !(A|B)

Demos

I'll often times use echo so I can see what the globstar or extended globbing will work out to be without actually running a real command on the expanded lists of files and/or directories.

Example

Say for example I have the following directory of files.

$ ls -l
total 8
-rw-rw-r-- 1 saml saml    0 Nov 15 20:12 a
drwxrwxr-x 2 saml saml 4096 Nov 15 20:23 A
-rw-rw-r-- 1 saml saml    0 Nov 15 20:12 b
drwxrwxr-x 2 saml saml 4096 Nov 15 20:12 B
-rw-rw-r-- 1 saml saml    0 Nov 15 20:12 c
-rw-rw-r-- 1 saml saml    0 Nov 15 20:12 d
-rw-rw-r-- 1 saml saml    0 Nov 15 20:12 e
-rw-rw-r-- 1 saml saml    0 Nov 15 20:12 f

Now if we try out the above expansions we can see how they'd fair.

$ echo [a-d]
a A b B c d

$ echo {a..d}
a b c d

$ echo a* b*
a b

$ echo !(B)
a A b c d e f

$ echo !(A|B)
a b c d e f

Extended globbing

There are a variety of other methods you can use to control the way that the shell matches. For example:

  ?(pattern-list)   Matches zero or one occurrence of the given patterns
  *(pattern-list)   Matches zero or more occurrences of the given patterns
  +(pattern-list)   Matches one or more occurrences of the given patterns
  @(pattern-list)   Matches one of the given patterns
  !(pattern-list)   Matches anything except one of the given patterns

You can read more about them in this Linux Journal article titled: Bash Extended Globbing.

7
  • Or xdg-open {a..d}
    – Bernhard
    Nov 15, 2013 at 21:53
  • @Bernhard - thanks, I added it to Q. You could've edited it in yourself, I don't mind.
    – slm
    Nov 15, 2013 at 21:55
  • I'm guessing the OP doesn't actually have files called a...d.
    – Joseph R.
    Nov 15, 2013 at 22:47
  • @JosephR. - yeah sorry I stubs this out today at work but then got busy and didn't' finish it as I had planned then. See it now, this was what I had in mind.
    – slm
    Nov 16, 2013 at 1:28
  • It's still dependent on file names being easy to match via single-letter globs. How can I adapt this solution to a situation where I have files called foo, bar and glarb?
    – Joseph R.
    Nov 16, 2013 at 1:30
0

Using the zsh shell (from e.g. an interactive bash shell):

zsh -c 'xdg-open A/*(.)'

This would use the . glob modifier in zsh that makes A/* only match regular files under the A directory. To also match symbolic links to regular files use A/*(-.) as the globbing pattern.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .