I got excited when I saw the 'f' and 'count' commands, but they're just scripts he has on his system. Like doing grep 'plover' blah.log | cut -d ' ' -f 11 | sort | uniq -c | sort -n. Personally I'd prefer to use the ubiquitous commands that work everywhere than rely on having custom scripts on my system, but they are nice.
Most people who use Unix directly build up some stuff in ~/bin (often a misnomer because it's shell scripts and not binaries, although mine is less of a misnomer than most because so much is in C rather than shell). The trick is to build them out of the standard portable components that exist everywhere. (This means, among other things, no #!/bin/bash.)
Benchmarking shell pipelines and the Unix “tools” philosophy
51–60 of 66 posts
Re: Benchmarking shell pipelines and the Unix “tools” philosophy
#52I got excited when I saw the 'f' and 'count' commands, but they're just scripts he has on his system. Like doing grep 'plover' blah.log | cut -d ' ' -f 11 | sort | uniq -c | sort -n. Personally I'd prefer to use the ubiquitous commands that work everywhere than rely on having custom scripts on my system, but they are nice.
grep 'plover' blah.log | cut -d ' ' -f 11
I usually do awk '/plover/{print $11}' blah.log
Less typing, but probably not as easy to understand.Re: Benchmarking shell pipelines and the Unix “tools” philosophy
#53Thanks for this! Another nice thing about /usr/bin/time is the --verbose flag which gives: Command being timed: "ls" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 0% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size…
Can anyone comment why you can only use the verbose flag if you use the full path of time? time -v ls does not work but /usr/bin/time -v ls does? I don't have enough knowledge of either linux applications or bash to know whats happening to cause this.
Re: Benchmarking shell pipelines and the Unix “tools” philosophy
#54Thanks for this! Another nice thing about /usr/bin/time is the --verbose flag which gives: Command being timed: "ls" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 0% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size…
Can anyone comment why you can only use the verbose flag if you use the full path of time? time -v ls does not work but /usr/bin/time -v ls does? I don't have enough knowledge of either linux applications or bash to know whats happening to cause this.
Re: Benchmarking shell pipelines and the Unix “tools” philosophy
#55Earlier quoted context omitted.
Not explaining, trying to tell that you are comparing apples to oranges and making a conclusion based on that. Also, you don't need to spawn a subshell nor feed sort via stdin in the first example :)
He's comparing apples to oranges and reaching the conclusion that... yes, apples and oranges are different things. He's quite aware of this, and even points out the tradeoff -- `sort | uniq -c` still works if your dataset doesn't fit into RAM.
Heck, forget about RAM, the output of both programs don't even match.
That awk is pretty efficient and fast is no surprise ;)
Re: Benchmarking shell pipelines and the Unix “tools” philosophy
#56Earlier quoted context omitted.
Not only GNU sort, but also postgresql, mysql and many more... Please, "huge waste"? How do you sort something that does not fit in memory?
Are you being difficult on purpose? I posted a comment on how 'sort | uniq -c | sort -n' is an interesting and very capable pipeline, but often misused and slower than other alternatives. > you are comparing Yes, I am comparing two methods of accomplishing the same thing. That is how comparing things works. > Please, "huge waste"? How do you sort something that does not fit in memory? Note how the full sentence inclu…
Programming is about paying the bare minimum attention to the details.
> [...] two methods of accomplishing the same thing [...]
Absolutelly not.
one prints:
72000000 hello
72000000 world
the other hello 72000000
world 72000000
Now try both examples against a file with more than one column to understand what I'm talking about ;)Re: Benchmarking shell pipelines and the Unix “tools” philosophy
#57Thanks for this! Another nice thing about /usr/bin/time is the --verbose flag which gives: Command being timed: "ls" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 0% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size…
Can anyone comment why you can only use the verbose flag if you use the full path of time? time -v ls does not work but /usr/bin/time -v ls does? I don't have enough knowledge of either linux applications or bash to know whats happening to cause this.
\time -v ls
to skip the builtin version.Re: Benchmarking shell pipelines and the Unix “tools” philosophy
#58Earlier quoted context omitted.
You are overly pedantic on a detail point that doesn’t matter: yes shell scripting is technically a programming language, but my point is that it is a terrible one worth ditching for any non trivial task. Perl was created precisely more than 3 decades ago to address this problem. Nowadays there are alternatives such as Python, Powershell or even scripting wrapper for compiled languages (such as C#) that allow to do t…
I disagree with you wholeheartedly and without condition. Not only are you discounting how much time it takes to learn how to program effectively in a real 'glue' language you are high handed in ignoring the ubiquity, working archive and efficacy of a shell script. Not to mischaracterize but I find this type of attitude most frequently in 'lead' individuals with less than 10 years experience: typically 20's and 30's…
Re: Benchmarking shell pipelines and the Unix “tools” philosophy
#59'sort | uniq -c | sort -n' is an interesting pipeline. It will always work and does a great job with large cardinality data on low memory systems. However, if you have the ram, or know the data set has a low cardinality (like, http status codes or filesnames instead of ip addresses) then something that works in memory will be much more efficient. I threw 144,000,000 'hello' and 'world' into a file: justin@box:~$ ls -…
All of your examples work in memory.
Awk includes an asort() function which can sort an array, such that it would be possible to create a similar process entirely within awk to the sort | uniq -c pipeline:
#!/usr/bin/gawk -f
{ x[NR] = $1 }
END {
rc = asort(x)
j=0
for(i in x) {
if( x[i] "" == x[i-1] "" ) freq[j]++
else {
j++
elem[j] = x[i]
freq[j] = 1
}
}
for(j in elem) {
printf( "%6i %s\n", freq[j], elem[j])
}
}
As compares with a hash-based counter: #!/usr/bin/gawk -f
{ x[$1]++ }
END { for(i in x ) printf( "%6i %s\n", x[i], i ) }
On a 2,000 value test dataset with 10 unique values:sort | uniq -c takes 0.019s (8 runs averaged)
awk hash takes 0.023s (8 runs averaged)
awk-implemented sort + unique takes 0.33s (8 runs averaged)
In this case, sort | uniq is the fastest option. But the all-in-memory sort + separate tabulation of unique values in awk is notably slower (running in 143% of the time) than the also all-in-memory hash accumulator.
As I bump up the dataset size (20,000 records) that discrepency increases, roughly 0.052s sort|uniq, 0.065s hash, and 0.217s ask sort-unique.
TL;DR: test your assumptions, especially regarding performance.
Note: Data were generated with a simple bash loop:
for i in {1..2000}; do echo $((RANDOM%10)); done > dataRe: Benchmarking shell pipelines and the Unix “tools” philosophy
#60Indeed.