Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

gnat (29)

  (email not shown publicly)

Journal of gnat (29)

Tuesday August 27, 2002
11:08 PM

Idiom du jour

[ #7354 ]
Have you let xargs into your life? xargs is designed to get around the shell's limitation of the number of arguments a program can take. xargs takes lines of input and turns them into commandline arguments:

ls -1 | xargs chmod 755

repeatedly runs the chmod command with a bunch of filenames per invocation until all the output of ls is consumed.

But xargs has a fatal flaw. Spaces in filenames screw it up.

So my shell idiom of choice is now something like:

ls -1 | perl -e 'chomp(@args = <>); while (@args) { @a = splice(@args, 0, 50); system("chmod", "755", @args) }'

(though I'd use Perl's built-in chmod rather than shelling out, in this case).

The case that inspired it was fixing the id3 tags on my mp3 files:

find . -name \*.mp3 -print | perl -e 'chomp(@args=<>); while (@args) { @a = splice(@args, 0, 50); system("id3convert", @a) }'

Change 50 to however many arguments per command you want.


The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • I'm probably missing something obvious here, but can't you just throw a backslash before any space in one of the arguments? That is, just use something like:

    ls -1 | perl -pe 's/ /\\ /g' | xargs chmod 755

    The more usual (and more comprehensive) way 'round this seems to be to use "find" for everything, and then combine find's "-print0" option with the -0 option to xargs. But that doesn't help much with a simple pipe from "ls".

    • If you have GNU ls, you can use -Q.

      ls -Q | xargs chmod 755

      If you don't have it, you know the motto : Get New Utilities.

    • I have been using xargs with space-riddled filenames for many years, as shown by examples below:

      find . -print0|xargs -0 chmod 755 (GNU only)
      find . -print|sed 's/ /\\ /g'|xargs chmod 755 (works everywhere)
    • Well bugger, I live and I learn! Thanks to everyone who pointed out print0.

      Well, the Perl idiom of sucking a bunch of array elements off at a time still stands, but now I feel SUPERHUMAN with my new-found shell fu.

      use.perl to the rescue!