When working with the output of commands such as locate which produce lists of paths in "human readable form" (i.e. without \ in front of spaces), how do you redirect their output to another command?

The output of $ locate [something] produces paths with spaces in them, which inhibits other programs to use the paths in the case they contain spaces. For example, if I were to

$ du -h `locate *.doc`

this will produce an error on all files and directories that contain spaces. (wrapping the ticks in spaces does not work)

  • Honestly, this is the second time I've had this problem in two days, in a different context. – rien333 Apr 24 '17 at 21:27
  • 1
    We got confused. Is the solution bellow with find or locate -0 acceptable? If not, why? – George Vasiliou Apr 24 '17 at 21:55
  • In the cases where the list of human readable paths is separable/separeted by ASCII NULL characters it is an acceptable answer. The solution bellow might thus not be as generalizable as I had meant, but if I had a procedure for making sure that the list produced by command1 is NULL separated $ [command1] | xargs -0 [command2] will accomplish what I want. – rien333 Apr 24 '17 at 22:10
  • 1
    Using locate -0 or find -print0 as advised in bellow answer will generate a null separated list of files/paths; xargs will handle this null byte separation and will feed correctly du utility. So, bellow answer is your solution. There is nothing more rigid to overcome special chars (like spaces) in filenames/pathnames than using tools which support null byte separated results (and both locate and find can null separate their results) – George Vasiliou Apr 24 '17 at 22:15
  • 1
    @rien333 - there is no such thing as a "list of human readable paths separated by null chars". If the items in your list are null separated then the list is no longer "human readable"... – don_crissti Apr 24 '17 at 22:17

What is the specific reason you're using locate? This appears to do what you have asked for:

find . -type f -name '*doc' -exec du -h "{}" \;

That said, if you really do want do use a tool like locate or find and pass its input as parameters to another program, you can avail yourself of the NUL delimited output and input that some tools provide. locate and find both have an option (locate's -0 and find's -print0) which will allow you to have more programatically-friendly output, which xargs is designed to read with its -0 argument:

find . -type f -name '*doc' -print0 | xargs -0 du -h

locate -0 '*doc' | xargs -0 du -h
  • While I understand that I should be using find, I would rather know how to do this in a nice manner anyway. I personally do prefer locate however because 1. i am a noob 2. the syntax seems simpler 3. habits/it gets the job done. – rien333 Apr 24 '17 at 21:34
  • I'm still wondering if you can do this without -0 flags, but if you use locate -0 this answer works for my example. – rien333 Apr 24 '17 at 21:41
  • 1
    -0 is the magic sauce that makes this work. It uses a NUL character explicitly to delimit the returned entities, and xargs is told to expect this, so whitespace is not used for parameter separation. Happily, locate also has a -0 parameter. – DopeGhoti Apr 24 '17 at 22:06
  • 1
    @DopeGhoti In case of find you could use find -exec instead of piping to xargs, right? – George Vasiliou Apr 24 '17 at 22:09
  • 2
    True, find . -type f -name '*doc' -exec du -h "{}" \; does work; I for some reason was thinking that it would run du for each result found. I blame the fact that it's Monday. – DopeGhoti Apr 24 '17 at 22:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.