5 ms·
For me it was definitely find. I went through a ton of contortions to replicate its behavior several times before somebody knowledgeable clued me in. Also, ``
by tikhonj 15y ago
For me it was definitely find. I went through a ton of contortions to replicate its behavior several times before somebody knowledgeable clued me in.
Also, `` and $(). Find combined with one of these is great. One of my favorite one-liners (I even figured it out myself :)) is:
cat `find . --name *.java` | wc -l
- sbov 15y agoNever thought to use ``. I always used xargs: find . -name *.java | xargs cat | wc -l
- cperciva 15y agoYour approach works better than backtick expansion, since it won't run into 'command line too long' issues; but it will still break on "weird" file names (e.g., file names with spaces in them). The correct way to do this is find . -name *.java -print0 | xargs -0 cat | wc -l
- ars 15y agoBTW, recent versions of linux don't have a fixed limit on command line length. The command line can be a large as available memory (for a single processes). (Although the ratio between command line length and allocated memory is not obvious since it depends on the number of words in the command line.)
- ralph 15y agoThat glob could cause trouble. find . -name '*.java' -print0 | xargs -0 cat | wc -l
- pyre 15y agoxargs can still run you into the 'too many args' issue. You'll want to use this: --max-args=max-args -n max-args Use at most max-args arguments per command line. Fewer than max-args arguments will be used if the size (see the -s option) is exceeded, unless the -x option is given, in which case xargs will exit.
- cperciva 15y agoOnly if there's a bug in your xargs. POSIX states: The xargs utility shall limit the command line length such that when the command line is invoked, the combined argument and environment lists (see the exec family of functions in the System Interfaces volume of POSIX.1-2008) shall not exceed {ARG_MAX}-2048 bytes so you should never run into the ARG_MAX limit.
- sirn 15y agoWithout xargs: find . -iname '*.java' -exec cat {} + |wc -l But if you do that, why not just: find . -iname '*.java' -exec wc -l {} + Which will also print out output of wc -l for each files along with total lines.
- dredmorbius 15y agoDollar-paren expansion beats backticks for being nestable. E.g.: I like dumping temporary files with timestamps: some-command-to-generate-log > /tmp/log-$( date +%Y%m%d-%H%M%S ) Now, if I want to wrap that in a larger loop -- say, iterating over a number of files or parameters: command $( expansion one $( expansion 2 )) Works With backticks you'd have to do escapes: command `expansion 1 \`expansion 2\` ` ... which gets tedious.
- jbarber 15y agoI like to use (for GNU date at least): $ date -Iseconds 2011-11-21T10:56:17+0000 because it requires less typing. The ISO 8601 standard format. -Is, -Im, -Ih, and -Id allow you to change the displayed resolution. Bizarrely, this doesn't seem to be documented in my version of date (coreutils 8.10).
- dredmorbius 15y agoA lot of the date documentation is unfortunately in info only. Debian (and derived distros) do a good job of updating the manpages. That said, I can't find "-I" documented anywhere. What I like about the timestamp I use is that it's semantic but sorts lexically as well. Though yours does as well. Hrm.
- asharp 15y agoAlso remember find's -print0 and xargs -0 so that you can deal with all filenames.
- thelastnode 15y agoFor find, you need to use single quotes so your shell doesn't automatically expand the .java glob into the names of all the files. Also, find uses one dash for parameters, and can take an exec parameter: find . -name .java -exec wc -l {} \; The {} means "replace with filename" and the semicolon (escaped so your shell doesn't eat it). This will run wc -l <filename> for every file that matches. The -regex flag lets you do the same thing as -name with regular expressions. The problem with this is we run n different wc's, as opposed to just one with all the parameters. We can use xargs to fix this: find . -name .java | xargs wc -l This even gives you a total! The really* simple solution (which is probably best) is to just use shell globbing: wc -l *.java While find and xargs are definitely useful, the easy solution here works better
- sirn 15y agoYou can skip xargs altogether with the plus sign instead of semicolon. -exec utility [argument ...] {} + Same as -exec, except that ``{}'' is replaced with as many path- names as possible for each invocation of utility. This behaviour is similar to that of xargs(1). The problem with just wc -l *.java is that it don't recursive directory.
- jedbrown 15y agoWith bash-4 or zsh wc -l **/*.java
- sjs 15y agoYou'll want to quote .java so the shell doesn't interpret it as a glob, and find doesn't use GNU style flags. You can also pass wc the filenames directly like this: wc -l $(find . -name '*.java')
- jedbrown 15y agoThat has different semantics (it prints one line per file) and can have line length limitations. This has the same semantics as the parent's version, but without line length issues. find . -name \*.java -exec cat {} + | wc -l
- X-Istence 15y agoNote that the + may not be portable. I know it doesn't work on older Solaris versions (<10) and HP-UX (from a couple years ago when I last touched it). Also, find may or may not split the files it finds into multiple invocations.
- Karellen 15y agoToo many invocations of "cat" find . -name \*.java -print0 | xargs -0 cat | wc -l Edit: Dammit. Others have already posted this exact version further below. :-(
- tikhonj 15y agoYeah, the flags always get me. For some reason, I've never had issues with the *. It's good to know about passing files to wc directly. I just use M-x find-dired and friends these days for most things, admittedly.
- re_todd 15y agoAgree with "find", especially finding files with recent changes, e.g. in last 5 minutes: find . -mmin -5 -print
- reinhardt 15y agoI was an avid find user until I discovered ack-grep. These days it's one of the first things I sudo apt-get install.
- gnosis 15y agozsh's extended globbing support makes the use of find unnecessary in most cases. See the "extended globbing" section of the link below[1] for some examples. zsh also has the 'zargs' command, which works something like xargs, except that it gets its arguments from the command line (often in conjunction with extended globbing) rather than from stdin. You might also be interested in reading about the "useless uses of cat"[2] [1] - http://linuxgazette.net/184/silva.html http://linuxgazette.net/184/silva.html [2] - http://partmaps.org/era/unix/award.html http://partmaps.org/era/unix/award.html
- alextingle 15y agoIn zsh: cat **/*.java | wc -l
- chalst 15y agoBash got this functionality in v4. It's not as useful as find.