How can I use -0 option to xargs when specifying the input manually?

13,772

Solution 1

For example - as told in the man xargs

-0 Change xargs to expect NUL (``\0'') characters as separators, instead of spaces and newlines. This is expected to be used in concert with the -print0 function in find(1).

find . -print0 | xargs -0 echo

The -0 tells xargs one thing: "Don't separate input with spaces but with NULL char". It is useful usually in combination with find, when you need handle files and/or directories that contain space in their name.

There are more commands what can play with -print0 - for example grep -z.

Edit - based on comments:

See Seth's answer or this:

ls -1 | perl -pe 's/\n/\0/;' > null_padded_file.bin
xargs -0 < null_padded_file.bin

But it is strange, why want use -0 if you don't need to use it?. Like "Why want remove a file, if does not exist?". Simply, the -0 is needed to use only with combination, if the input is null-padded. Period. :)

Solution 2

xargs works differently than you think. It takes input and runs the commands provided as arguments with the data it reads from the input. For example:

find dir* -type f -print0 | xargs -0 ls -l

ls -d dir* | xargs '-d\n' ls -l

look foo | xargs echo

look foo | perl -pe 's/\n/\0/;' | xargs -0 echo

You often use -0 if you suspect the input might have spaces or returns embedded in it, so the default argument delimiter of "\s" (regular expression \s, space, tab, newline) isn't good.

Share:
13,772
Ankur Agarwal
Author by

Ankur Agarwal

Updated on August 04, 2022

Comments

  • Ankur Agarwal
    Ankur Agarwal over 1 year

    I have

    ~/bashpractice$ ls
    dir3 dir1   
    

    I get

    ~/bashpractice$ xargs ls -l 
    dir1 dir3
    dir1:
    total 0
    -rw-r--r-- 1 abc abc 0 2011-05-23 10:19 file1
    -rw-r--r-- 1 abc abc 0 2011-05-23 10:19 file2
    
    dir3:
    total 0
    -rw-r--r-- 1 abc abc 0 2011-05-23 10:20 file1
    -rw-r--r-- 1 abc abc 0 2011-05-23 10:20 file2
    

    But I get an error when I do

    ~/bashpractice$ xargs -0 ls -l
    dir1 dir3
    ls: cannot access dir1 dir3
    : No such file or directory
    
    abc@us-sjc1-922l:~/bashpractice$ xargs -0 ls -l
    dir1
    dir3 
    ls: cannot access dir1
    dir3
    : No such file or directory
    

    How to get a listing when specifying -0 option to xargs ?

  • Ankur Agarwal
    Ankur Agarwal almost 13 years
    Can I not use xargs -0 without using it with find ?
  • Ankur Agarwal
    Ankur Agarwal almost 13 years
    How do I null pad input to xargs ? I think I do not know how to do that. I tried including \0 as a terminating character to directory names and that did not work.
  • Seth Robertson
    Seth Robertson almost 13 years
    @Ignacio Vazquez-Abrams: using xargs with tty input is almost always a sign of incorrect thinking, especially if you are providing all of the arguments on one line of input. Even moreso with xargs -0. Unless you are trying to turn a cut-n-paste of items into arguments to a command (e.g. paste a return separated list of filename into arguments to ls -l) you don't want to use xargs interactively. xargs is designed for use in a pipeline of commands.
  • Seth Robertson
    Seth Robertson almost 13 years
    @abc: Check my answer above. I provide an example where I turn newline separated input into null separated input.
  • Ankur Agarwal
    Ankur Agarwal almost 13 years
    Please look at my original question. I am trying to run xargs successfully for the second attempt ( one giving an error) above.
  • Ankur Agarwal
    Ankur Agarwal almost 13 years
    @Seth, I understand that I should not use xargs the way I am using ( second attempt in my original post). But are you saying there is no way I could use/run xargs (without errors) like that ?
  • Ankur Agarwal
    Ankur Agarwal almost 13 years
    @Seth, But you are using xargs -0 in a pipeline. I want an example where xargs -0 is not being used in a pipeline.
  • Seth Robertson
    Seth Robertson almost 13 years
    @abc: The argument you are passing to ls is "dir1\ndir2\n" A filename with two embedded newlines in it. It is entirely possible to create a filename with two embedded newlines in it, so in theory this could actually do something useful. But in practice not so much. You cannot type a ASCII NULL at a normal shell prompt so you could never provide more than one argument. As such, "xargs -0" is unlikely to be the droid you are looking for.
  • Ankur Agarwal
    Ankur Agarwal almost 13 years
    @jm666 If you have an example using xargs -0 standalone ( not in a pipleline) , please provide that.
  • Seth Robertson
    Seth Robertson almost 13 years
    @abc: No problem. Example away: echo -e "dir1\ndir2" | xargs -0 mkdir; emacs .; echo -e "dir1\ndir2" | xargs -0 rmdir You can physically type "dir1 <return> dir2 <return> <control-d>" in place of the echo if you want. emacs . is showing you the directory you created with the embedded newline (`ls -l) cannot show that. There are easier ways of creating a filename with a newline in it, but it works. As I said above, you cannot pass in multiple arguments from the keyboard. You cannot type the NUL character.
  • Ankur Agarwal
    Ankur Agarwal almost 13 years
    @Seth I see. ASCII NULL cannot be typed on the shell. What about '\0' ?
  • Seth Robertson
    Seth Robertson almost 13 years
    @abc: \0 is C-talk for ASCII NUL. Same character. Some programs like "echo" can generate it, but you cannot from the keyboard.