Question about wildcards in Unix

Discussion in 'Apple' started by JF Mezei, Jan 19, 2014.

  1. JF Mezei

    JF Mezei Guest

    Could someone explain why:

    cd ~
    ls -R *.c only lists .c files in the current directory
    ls -R */*.c will list .c files in any subdirectory

    if one supplies the -R, shouldn't the first command parse through the
    whole tree below the current location and yield the same results as the
    second command ?

    I've never quite had a good grasp of Unix wildcarding of files because
    of differences from my hardwired VMS experience. Is there some good
    place to get the authoritative description on how file wildcarding works
    in Unix/Bash/freebsd ?
    JF Mezei, Jan 19, 2014
    1. Advertisements

  2. JF Mezei

    Siri Cruz Guest

    The shell matches all patterns in the command and insert them into the command
    before execking the program. When you type in
    ls -R *.c
    The shell search the current directory and finds maybe a.c and b.c. The shell
    matches them and then execs
    "/bin/ls" "-R" "a.c" "b.c"
    If you have subdirectory c with d.c and e.c the shell will not match them. But
    ls -R *.c */*.c
    the shell will match them and execs
    "/bin/ls" "-R" "a.c" "b.c" "c/d.c" "c/e.c"

    The ls never sees the patterns unless you type
    ls -R '*/*.c'
    but even then ls will interpret '*/*.c' as the actual file name rather than a

    The proper way to search recursively search on pattern is the find command
    find . -name '*.c'
    The single quotes around *.c prevent the shell interpretting it as a pattern and
    substituting matching names. So the shell execs
    "/usr/bin/find" "." "-name" "*.c"
    find then starts with the directory . (the current directory) and recursively
    looks for any directory entry (file name) that matches the pattern *.c and
    prints the paths of what it finds.
    Siri Cruz, Jan 19, 2014
    1. Advertisements

  3. no, but the first command would recursively list the entire contents
    of any directory with a name ending in '.c'.
    it's worthwhile experimenting with 'echo' to see how wildcards are
    expanded in any particular case

    I recommend any of the O'Reilly books on unix or shells

    Joanna Shuttleworth, Jan 19, 2014
  4. JF Mezei

    JF Mezei Guest

    That is the problem. It doesn't do that. It only lists .c files present
    in the current directory and does not go into subdirectories to look for
    other .c files.
    JF Mezei, Jan 19, 2014
  5. JF Mezei

    David Empson Guest

    Read what nospam said again.

    If the current directory contains a subdirectory which has a name ending
    in ".c", then "ls -R *.c" will recursiely list the entire contents of
    that subdirectory (and any other similarly named subdirectories in the
    current directory).

    It will also list any files in the current directory which have names
    ending in .c.

    This is because the "*.c" wildcard in "ls -R *.c" is expanded by the
    shell, replacing it with the name of all files and subdirectories in the
    current directory, before the whole command is passed to ls.

    For example, if the current directory contained files a.c and b.c, and a
    subdirectory called more.c, then "ls -R *.c" would be expanded by the
    shell to "ls -R a.c b.c more.c". The ls command would list the files a.c
    and b.c, then the entire contents (recursively) of the more.c
    subdirectory (all files in that subdirectory would be listed, not just
    filenames ending in ".c").

    As Siri Cruz said, the "find" tool is a better way to do what you want:

    find . -name '*.c' -print

    This will list all files in the current directory and recursively in all
    subdirectories which have a name matching the pattern '*.c'.

    In this case, the '*.c' is not expanded by the shell because of the
    single quotes. It gets passed to the find command, which uses it as a
    pattern to match.

    The second command you used (ls -R */*.c) is also not doing quite what
    you think it is doing.

    In this case, the shell will expand */*.c to all files with names ending
    in ".c" which are in all first level subdirectories of the current
    directory, then pass them to ls, which will list them. It won't list any
    ".c" files in the current directory, nor in any second level (or deeper)

    The -R option only comes into play if any of the files in the first
    level subdirectories happen to be a subdirectory with a name ending in
    ".c", in which case ls will also list the entire content of that
    subdirectory recursively.
    David Empson, Jan 19, 2014
  6. JF Mezei

    Guest Guest

    it wasn't me. i haven't been a part of this thread (until now).
    Guest, Jan 20, 2014
  7. JF Mezei

    JF Mezei Guest

    Ahh. Thanks I understand now.

    So, if I want to grep "mystring" in all C programs below current
    directory, how do I go about it ?

    So basically, -R (or -r depending on utility) only works when the
    wildcard includes all files so it grabs directory files as well as the
    files you are looking for.

    But "find" doesn't help me with tools like grep and others.
    JF Mezei, Jan 20, 2014
  8. JF Mezei

    David Empson Guest

    Sorry, temporary brain fade. I should have said Joanna.
    David Empson, Jan 20, 2014
  9. Find is youir friend.
    find . -name \*.c -exec grep mystring {} \;

    Read the manual page of find (man find). Find is your friend for this
    kind of tasks, it can do all of that and more. Find is only a bit
    prickly on the outside.
    A long time ago there was this bug mentioned in the manual page:
    The syntax is painful.

    And so it is.

    Maarten Carels, Jan 20, 2014
  10. JF Mezei

    Tim Streater Guest

    And it is this painfullness which causes me, five minutes after I
    foolishly decide I should learn a bit more about shells, to eject the
    computer through the window at high velocity. This happens from time to
    Tim Streater, Jan 20, 2014
  11. You didn't read carefully what Joanna wrote.

    It will recurse into other directories _if the directory name matches
    *.c_. Of course then it will give you _all_ files in those

    In other words, the command actually does what you are telling it to,
    just not what you want it to.
    Doug Anderson, Jan 20, 2014
  12. I'll keep away from the sidewalk below your window. Realize though
    that the shell is extremely powerful (as are commands like "find,"
    horrible though the syntax is). So 5 minutes is not enough time to
    learn more!
    Doug Anderson, Jan 20, 2014
  13. JF Mezei

    JF Mezei Guest

    If it takes an hour to find out the correct invocation of a command, you
    might still call the shell powerfull, but is it usefull?

    in vms:

    search [...]*.c mystring

    the [directory...] semantic is the "recursive" which will traverse all
    directories below. [...] means anythimg below current dir.

    The big difference here is that filename search/expansion is done by the
    app, not the shell.

    The Unix way makes it simpler for apps since they are just given a long
    list of arguments (filenames to process). No need to have directory
    parsing. On the other hand, those very apps still need to have that
    logic when -r is specified because when they do encounter an argument
    which points to a directory , not a file, they must then do the parsing
    JF Mezei, Jan 20, 2014
  14. The more powerful a tool is, the longer it generally takes to learn
    how to use it fluently.

    Sometimes it takes me 30 seconds to figure out what command I need.
    Sometimes it takes me an hour. It all depends on how complicated what
    I'm trying to do is, and how much I already know about related

    The corresponding unix command is also short. The issue isn't "is
    there a command."
    Doug Anderson, Jan 20, 2014
  15. JF Mezei

    Tim Streater Guest

    I don't see that this necessarily follows.
    Based on the two (2) occasions when I've been fool enough to launch
    emacs, it takes me 20 minutes to find out how to quit it.

    If I need to edit anything I use TextWrangler, (or perhaps vi), and if
    I need a script I write it in PHP.

    I've learnt a few simple commands like fgrep for doing multi-file
    searches. hexdump is useful sometimes for verifying that a file has the
    content I believe it to have. But for everything else, there's probably
    a GUI app. PacketPeeper is all I need to spy on packets on the wire,
    Tim Streater, Jan 20, 2014
  16. JF Mezei

    Guest Guest

    not if it's designed well.

    powerful does not mean complicated.

    in fact, it's the opposite. easy to use is when something is powerful
    because it empowers more people to be able to do more things, rather
    than throw up their hands and give up in frustration.
    Guest, Jan 20, 2014
  17. A light switch is very simple. It does one thing - turn the power off
    and turn the power on. Easy to learn how to use, not very powerful.

    A TV remote by contrast needs to do many things. It can do far more
    than turn a TV off and on, and has to be able to do far more than
    that. But it is much harder to learn how to use than a light switch,
    even if it is the world's best designed TV remote..
    20 minutes! You must have very slow internet service. I typed "how
    do I quit emacs" into google, and had the answer in well under a
    minute. (Though I actually know how to quit emacs - I was just seeing
    how long it would take.)

    Again, emacs is an incredibly powerful and useful text editor - the
    things I use it for would take 20 times as long for me in
    TextWrangler. But yes, learning how to use it required an investment
    in time over the years.
    By "for everything else" you mean everything else that _you_ do. And
    that's fine - I'm not trying to talk you or anyone else into learning
    how to use the unix shell.

    I'm just pointing out that one of the reasons it is hard to learn how
    to use is that it is incredibly powerful. It is hard to learn how to
    use a TV remote than a light switch. You can turn your TV on and off
    with a light switch if you set things up that way, but you won't be
    able to change channels, switch inputs, change volume, adjust the
    picture, etc. with a light switch.

    The right tool for the right job. If you have no jobs for which the
    unix shell is the right tool, then by all means stay away from it.
    But it is naive to think that the unix shell is defective because you
    can't learn how to use it in 5 minutes.
    Doug Anderson, Jan 21, 2014
  18. A powerful tool designed well is harder to learn how to use than a
    more limited tool designed well.

    If you don't see that, then I don't know how to convince you.
    Correct. But as a rule tool that can do many different things is
    going to be harder to understand and use than a tool that can just do
    one thing.
    The unix shell has empowered me to do a _lot_ of things. Tim threw up
    his hands in frustration because he didn't actually need it - he had
    other tools that were better suited. That's a good thing.

    I _could_ use the unix shell to make .xml files. I use perl instead
    because it is better suited to that. This isn't a knock on the power
    of the unix shell.
    Doug Anderson, Jan 21, 2014
  19. JF Mezei

    Tim Streater Guest

    A powerful tool designed well should be no harder to use for simple
    things than a simple tool that can only do those simple things. And if
    that is the case, the user is thereby encouraged to explore a bit and
    eventually learn to use the tool for more complex actions.
    But it shouldn't be *that* much harder.
    There's quite a lot in TW that I don't use, and guess what, for the
    things that I do use it for, it behaves pretty identically to notepad,
    a much simpler tool.
    Which tool give you this? :)
    Tim Streater, Jan 21, 2014
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.