4 ms·
I think you want s///g on your second sed... Also that doesn't work in Mac OS X for some reason (their sed doesn't appear to interpret \n in the replacement tex
by __david__ 13y ago
I think you want s///g on your second sed... Also that doesn't work in Mac OS X for some reason (their sed doesn't appear to interpret \n in the replacement text). I replaced it with perl to make that part work:
perl -pe 's/ *\| */\n/g'
I still haven't gotten the whole thing to work yet because my history contains the above history pipeline and so it's splitting the "|" that inside the sed command onto multiple lines which is causing "xargs which" to balk because quotes are not matching or something:
xargs: unterminated quote
Shells are amazing until spaces or quotes are involved! :-)
- ColinWright 13y agoYes, I've inserted the "g" in the appropriate sed commands. Thanks - good catch. Some systems seem to require \r instead of \n - I know vim's behavior differs from sed's in this, so that might be an issue. With xargs balking, you can throw the error stream at that point, for convert it to a loop over the alleged commands: for c in $( long thing before the xargs ) do which $c done \ | long thing after the xargs. Specifically: for f in $( \ history \ | sed "s/^[0-9 ]*//" \ | sed "s/ *| */\n/g" \ | awk '{print $1}' \ ) do which $f 2> /dev/null done \ | sed "s.^/usr.." \ | grep ^.bin \ | sed "s/^.*\///" \ | sort \ | uniq -c \ | sort -rn \ > commands.txt And yes spaces are a pig, and can lead to all sorts of ambiguities that don't have reasonable ways of resolving them, especially in filenames.
- __david__ 13y ago"\r" doesn't work either. It's just not interpreting those kind of escapes. I get lines like this: historyrsed "s/^[0-9 ]*//"rsed 's/ *r*/\r/g'rless The for loop is a good idea, though I prefer the "while read" idiom since it fits in with the pipeline better: ... | awk '{print $1}' \ | while read line; do which $line; done \ ... That finally works for me. Here's the whole thing: history \ | sed "s/^[0-9 ]*//" \ | perl -pe 's/ *\| */\n/g' \ | awk '{print $1}' \ | while read line; do which $line; done \ | sed "s.^/usr.." \ | grep ^.bin \ | sed "s/^.*\///" \ | sort \ | uniq -c \ | sort -rn
- lobotryas 13y agoFrom what I recall to represent s newline in sed on osx you need to add an actual carriage return. Take the poster's script above and copy it to a text file. Now replace \n with a new line, save and it should run.
- NyxWulf 13y agoThis works for me in zsh on OSX history \ | sed "s/^[0-9 ]//" \ | perl -pe 's/ \| */\n/g' \ | gawk '{counts[$1] += 1} END { for (x in counts) { print counts[x],x}}' OFS="\t" \ | column -t \ | sort -k 1,1nr \ | head -100 Ok not sure how to format this on HN https://gist.github.com/nyxwulf/5608955#file-gistfile1-sh https://gist.github.com/nyxwulf/5608955#file-gistfile1-sh