Find the answer to your Linux question:
Results 1 to 7 of 7
Hello, I've been using this command lately: Code: find . -type f -iregex '.*\.java' -exec egrep --color 'new Runnable' '{}' \+ The iregex and egrep pattern of course are not ...
  1. #1
    Just Joined!
    Join Date
    Nov 2010
    Posts
    5

    Question How to find files and then edit 'em (find,grep,vim)

    Hello,

    I've been using this command lately:
    Code:
    find . -type f -iregex '.*\.java' -exec egrep --color 'new Runnable' '{}' \+
    The iregex and egrep pattern of course are not important. The point is that at some point I find what I'm looking for and it could be a few files as match.

    How could I then easily start vim with those files ?

    A workaround by the way is to just open the file list in vim and then use the command 'gf' (go file). Like this:
    Code:
    find . -type f -iregex '.*\.java' -exec egrep --color -h 'new Runnable' '{}' \+ | vim -
    Maybe there's a better way ?

  2. #2
    Linux Newbie tetsujin's Avatar
    Join Date
    Oct 2008
    Posts
    115
    This should work, as long as the total number of files doesn't exceed ARG_MAX (IIRC, ARG_MAX no longer applies to Linux...)

    Code:
    vim $(find ...)
    This does choke on filenames with spaces in them, unfortunately... If you wanted the solution to be really robust in that regard, you could use xargs instead:

    Code:
    find ... -print0 | xargs -0 vi
    Or alternately:

    Code:
    find ... | xargs --delimiter='\n' vi
    The "-print0" option is more robust with regard to special characters inside of file names, but that limits the set of commands you can pipe the "find" results into. (Though less than I had thought!) "grep", fortunately, does seem to support null-byte as a delimiter, as does "sort". So you could do something like this:

    Code:
    find ... -print0 | grep -z pattern | xargs -0 vi
    xargs will collect lines on input and run vi one or more times to cover all the arguments. Generally you have to come up with thousands of inputs in order to make "xargs" run its command more than once - though exactly how many would depend on the specific platform...

  3. #3
    Just Joined!
    Join Date
    Nov 2010
    Posts
    5

    Smile

    Very nice answer .. and quick.
    Much thanks.

    Yes, the spaces and other stuff are a bi**h and therefore I'd never use a solution like:
    Quote Originally Posted by tetsujin View Post
    Code:
    vim $(find ...)
    Well, I suppose it's easy to remember and when dealing with my own programming files, it'd work so.. But the rest were fantastic and robust. Very nice.

    Btw, sensoring certain words with stars? I can't picture most of the regular users agreeing with that. I could be wrong..

  4. #4
    Linux Newbie tetsujin's Avatar
    Join Date
    Oct 2008
    Posts
    115
    Quote Originally Posted by denarced View Post
    Very nice answer .. and quick.
    Much thanks.

    Yes, the spaces and other stuff are a bi**h and therefore I'd never use a solution like vi $(find)
    Yeah, some people are more concerned with that sort of issue than others. Some people approach the issue by just making sure filenames never have spaces in them, or handwave the issue by saying that they never use spaces in filenames, and therefore it's not important... There was a "letters to the editor" in Linux Journal recently by someone complaining that all the shell programming examples ignored the problem - the response was, basically, "don't put spaces in your filenames"... But, like it or not, people do create files with spaces in the name. I don't usually do it myself but if I'm dealing with files I've downloaded, for instance, I may not have the luxury...

    I think commands like "vi $(find)" are a great way to express the user's intent, and it's just unfortunate that doing what the user really wants in that scenario requires a more complicated command. I'd really like to see that change... Going with the current design of shells like Bash, for instance, a reasonable solution might be to provide a version of the $() syntax which allowed specification of the field separator for expanding the command output into arguments. (Certainly Bash has no shortage of special variable expansion syntax...) Alternately, supporting null-byte as a delimiter in more tools (in particular, the shell itself - especially commands like "read") would solve a large number of problems related to writing commands like this in a reliable way...

    Btw, sensoring certain words with stars? I can't picture most of the regular users agreeing with that. I could be wrong..
    Can't say I'm a fan of it. As long as people aren't being disrespectful there's nothing wrong with a few colorful metaphors... And censoring commonly-abused words doesn't really address the matter of abuse in general.

  5. #5
    Just Joined!
    Join Date
    Nov 2010
    Posts
    5
    Quote Originally Posted by tetsujin View Post
    I think commands like "vi $(find)" are a great way to express the user's intent, and it's just unfortunate that doing what the user really wants in that scenario requires a more complicated command. I'd really like to see that change... Going with the current design of shells like Bash, for instance, a reasonable solution might be to provide a version of the $() syntax which allowed specification of the field separator for expanding the command output into arguments. (Certainly Bash has no shortage of special variable expansion syntax...) Alternately, supporting null-byte as a delimiter in more tools (in particular, the shell itself - especially commands like "read") would solve a large number of problems related to writing commands like this in a reliable way...
    Yes, the current situation is a little funny. Specifying the field separator easier than it is done now could be nice. I use find and its exec because of those spaces, whenever possible. It's an easy and clean solution. Whatever the solution may be, I doubt they'll do anything that's backward incompatible. Your suggestions also seemed backward compatible so they sound good..

  6. #6
    Trusted Penguin Cabhan's Avatar
    Join Date
    Jan 2005
    Location
    Seattle, WA, USA
    Posts
    3,230
    I would do this differently, from with Vim itself. There is a command :vimgrep that does basically exactly this:
    Code:
    :vimgrep /new Runnable/ *.java
    This populates the quickfix list with every line in the files named that matches the regex "new Runnable". You can navigate from match to match with :cnext, or if you just want to go to each file, you can use :cnfile.
    DISTRO=Arch
    Registered Linux User #388732

  7. #7
    Just Joined!
    Join Date
    Nov 2010
    Posts
    5
    Quote Originally Posted by Cabhan View Post
    I would do this differently, from with Vim itself. There is a command :vimgrep that does basically exactly this:
    Code:
    :vimgrep /new Runnable/ *.java
    This populates the quickfix list with every line in the files named that matches the regex "new Runnable". You can navigate from match to match with :cnext, or if you just want to go to each file, you can use :cnfile.
    Interesting, haven't really tested vim's limits. It's not unusual that I'm checking over 200 files and I think the last time I did this there were about 70 files. I'll have to test this.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...