Live data from Hacker News

Unix Commands I Abuse Every Day

everythingsysadmin.com

71–80 of 108 posts

Re: Unix Commands I Abuse Every Day

#71
post #2

My #1 abuse is xargs -n1. A lot of people like writing bash for loops, I will try and avoid that as much as possible, xargs -n1 is the bash equivalent of a call to 'map' in a functional language. For instance, let's say you want to create thumbnails of a bunch of jpegs: find images -name "*.jpg" | xargs -n1 -IF echo F F | sed -e 's/.jpg$/_thumb.jpg/' | xargs -n2 echo convert -geometry 200x Additionally, it's fully pa…

I too like xargs but see no need for these two xargs given sed is already used?

    find images -name '*.jpg' |
    sed 's/\.jpg$//
        s/.*/convert -geometry 200x &.jpg &_thumb.jpg/'

Re: Unix Commands I Abuse Every Day

#72
post #33
post #2

My #1 abuse is xargs -n1. A lot of people like writing bash for loops, I will try and avoid that as much as possible, xargs -n1 is the bash equivalent of a call to 'map' in a functional language. For instance, let's say you want to create thumbnails of a bunch of jpegs: find images -name "*.jpg" | xargs -n1 -IF echo F F | sed -e 's/.jpg$/_thumb.jpg/' | xargs -n2 echo convert -geometry 200x Additionally, it's fully pa…

I use xargs a lot for refactoring work when I cannot simply use sed, e.g. vim $(grep -lr foo | xargs) and doing what I need to do on a file by file basis. Otherwise, for renaming functions and the like, I do a lot of: find . -name foo_fn exec sed -i s/foo_fn/bar_fn/g '{}' \; I generally love abusing bash. Just today I was asked about how to rename a bunch of files, specifically containing spaces, and came up with eit…

Sorry, what do you think

    vim $(grep -lr foo | xargs)
is doing? Assuming a missing directory after the `foo' why can't it just be

    vim $(grep -lr foo .)
I don't see that xargs's default behaviour is adding anything.

For

    find . -name foo_fn exec sed -i s/foo_fn/bar_fn/g '{}' \;
you may find -exec's + of use. The above has the fork/execve overhead for each file found.

    find -name '*.[ch]' -exec sed -i 's/\/bar/g' {} +

Re: Unix Commands I Abuse Every Day

#73
post #60

Earlier quoted context omitted.

Why do that when a loop is clearer, safer, and shorter? find images -name '*.jpg' | while read jpg; do convert -geometry 200x "$jpg" "$(echo "$jpg" | sed 's/.jpg$/_thumb.jpg/')"; done This version works even when there are spaces in a filename, whereas yours will break.

false $ ls -Ql totale 4 -rw-r--r-- 1 zed users 33 set 6 07:30 " spaces " $ $ find -name '*spaces*' | while read text; do cat "$text"; done cat: ./ spaces: File o directory non esistente $ $ find -name '*spaces*' -print0 | xargs -0 cat while read is broken with spaces $

IFS needs some care and attention and read should have -r.

    $ ls -Q
    "   spaces   "
    $ ls | while IFS="\n" read -r f; do ls "$f"; done
       spaces   
    $
For lots of grim detail see David A. Wheeler's http://www.dwheeler.com/essays/fixing-unix-linux-filenames.h...

Re: Unix Commands I Abuse Every Day

#74

Earlier quoted context omitted.

find ./ -name '*.log' | xargs rm Only do that if you know exactly what '*.log' will expand to (i.e. don't use it in scripts and avoid using it on the command line). This is because the delimiter for xargs is a newline character, but filenames can have a newline character in them. This can lead to unexpected results. Almost everywhere I see xargs used, find ...-exec {} ; will work as well and find ...-exec {} + may wo…

find ./ -name '*.log' -print0 | xargs -0 rm Fixes that issue and xargs is far more efficient, it doesn't launch a new process for each line like exec does, but far more importantly, xargs is generalizable to all commands so you only have to learn it once; exec is just an ugly hack on find, you can't generalize it across all commands; xargs is much more unixy.

Wanting to remove the files was so common that some finds have it built-in. Avoids even the overhead of -exec rm {} +.

    find -name '*.log' -delete

Re: Unix Commands I Abuse Every Day

#75
post #6

Random note. The most commonly "abused" Unix command is cat. The name is short for "concatenate", and its intended purpose was originally to combine 2 or more files at once. Therefore every time you use it to spool one file into a pipeline, that is technically an abuse!

No, cat(1) stands for catenate, not concatenate. http://en.wiktionary.org/wiki/catenate

Re: Unix Commands I Abuse Every Day

#76
post #64
post #11

Earlier quoted context omitted.

I have long thought that some sort of zsh completion that detects that abuse of cat and converts it into the more appropriate `< file` might be a good idea. If it did it silently it probably wouldn't be worth it but if it actually preformed the substitution in front of you then it might help users get more comfortable with the carrot syntax.

Interestingly, there are some circumstances where you actually want "cat file | program" and not "program < file". The case I have in mind is when file is actually a named FIFO which was not opened for writing. If you use cat, program will still run and only reads to stdin will block (but it can perform other things, possibly in different threads). If you use '<', opening stdin will block and program will probably bl…

With < on a FIFO it's the shell that blocks on opening before the command, e.g. cat, is run.

Re: Unix Commands I Abuse Every Day

#77
post #20

fmt 1 i don't understand his first one though. i thought both linux and bsd greps had the -H option (show filename). here's some more: 1. sed t file instead of cat file 2. echo dir/*|tr '\040' '\012' instead of find dir 3. echo dir/*|tr '\040' '\012' |sed 's/.*/program & |program2 /' > file; . file instead of xargs or find (of course this assumes you keep filenames with spaces or other dangerous characters off your s…

The point of the first one is he's abusing grep as cat; what he really wants is a cat that shows filenames, but since there's no such thing he uses "grep ." as a substitute.

[deleted]

Re: Unix Commands I Abuse Every Day

#78
I use the "grep with color for lines plus the empty string" so frequently that I have a function for it:

  function highlight() {
    local args=( "$@" )
    for (( i=0; i
This is only to be used as a filter, since it mangles filenames.

I'm curious, does ack support a highlight-only mode?

Re: Unix Commands I Abuse Every Day

#79
post #57

I've come to use the following command so often that I've written a script for it in my ~/bin - 'narrow': #!/bin/bash xargs -n 1 grep -l "$@" This takes a list of files on stdin, then greps for the argument in all the files and spits out the matching files. The perk is that it can be chained: find *.txt | narrow dog | narrow cat | narrow rabbit This will find all the files that contain dog, cat, and rabbit.

But why run so many greps? I don't think there's a need for -n1 here.

    xargs -rd'\n' grep -l "$@"

Re: Unix Commands I Abuse Every Day

#80
post #2

My #1 abuse is xargs -n1. A lot of people like writing bash for loops, I will try and avoid that as much as possible, xargs -n1 is the bash equivalent of a call to 'map' in a functional language. For instance, let's say you want to create thumbnails of a bunch of jpegs: find images -name "*.jpg" | xargs -n1 -IF echo F F | sed -e 's/.jpg$/_thumb.jpg/' | xargs -n2 echo convert -geometry 200x Additionally, it's fully pa…

Is there a way to use an alias with xargs like in the command below ?

  xargs -a cmd_list.txt -I % alias %
This has been bothering me for a while.
Post reply on HN