bashfind

How to get the output of `find` as a space separated string?


I would like to list all the filenames inside a directory as a single argument string line that uses the Space character as separator.

Let's consider this directory:

/project
├─ foo bar.c
├─ bar is not baz.c
├─ you"are"doomed
└─ baz.c

An output to my problem would be:

. "./bar is not baz.c" ./baz.c "./foo bar.c" 'you"are"doomed'

Or

. foo\ bar.c bar\ is\ not\ baz.c baz.c you\"are\"doomed

Obviously it doesn't work with the null character \0 because this char cannot be processed on the arguments line:

find . -print0

. foo bar.c\0bar is not baz.c\0baz.c\0you"are"doomed

My goal is to pass these files to another program in this way

program `find . | magic` 

. foo\ bar.c bar\ is\ not\ baz.c baz.c you\"are\"doomed

EDIT (3 years later)

As identified by devsolar my question was a kind of a XY problem. His solution allows to pass the list of files to a program. However it does not answer the initial question completely.

The reason why I need an argument string is that I want to avoid to execute my program for each file found because it is too slow (especially on ).

Using xargs does not help either because it cannot escape all the chars. The closest to the solution I have been to is with this oneliner:

find . -print0 | perl -e 'local $/="\0";print join(" ",map{s/(?=["'"'"' ])/\\/gr}<STDIN>);'

. ./bar\ is\ not\ baz.c ./baz.c ./foo\ bar.c ./haha\"haha

Solution

  • Do

    find . -exec program {} +
    

    for calling program with a list of filenames as parameter. If lots of files are found, there might be more than one call to program to avoid too-long command line.

    Do

    find . -exec program {} \;
    

    to call program for each file found.

    Yes, this does work correctly with spaces in filenames.