1

Specifically, in mkinitcpio the command find -mindepth 1 -printf '%P\0' is used, what would be a way to recreate a command with identical output without the -printf flag. https://git.archlinux.org/mkinitcpio.git/tree/mkinitcpio This is the full script in case it is useful.

2
  • Do any of your file or directory names contain the newline character? Commented Sep 18, 2018 at 10:33
  • @meuh I don't know what files or directories it's finding, it's using it to find all the files to put into the initramfs. I don't see a reason the files or directories would have a newline character though. Commented Sep 18, 2018 at 13:18

2 Answers 2

0

%P will give the relative path of the file starting from the directory used as starting point, so that if find is run with some/path as starting point and it finds the pathname some/path/to/file, then %P will expand to to/file.

When GNU find is not given a starting point (as in the command given in the question), it will use the current directory (.) as the starting point. The %P format will therefore remove ./ from the found paths in this case.

To do the same thing as -printf '%P\0' with a non-GNU find implementations, assuming -mindepth is still available (as in find on BSD systems):

find . -mindepth 1 -exec sh -c '
    for pathname do
        printf "%s\0" "${pathname#./}"
    done' sh {} +

The embedded sh -c script will get a batch of pathnames from find to work on and uses a standard parameter expansion that removes the initial ./ from the pathname before printing it with a terminating nul-character.


The same thing, but with a variable holding the single top-level directory path:

topdir=/some/path

find "$topdir" -mindepth 1 -exec sh -c '
    topdir=${1%/}; shift
    for pathname do
        printf "%s\0" "${pathname#$topdir/}"
    done' sh "$topdir" {} +
1
  • -mindepth 1 can be written standardly with ! -name . or ! -path . Commented Feb 9, 2023 at 8:54
0

In -printf '%P\0' the %P is just removing the initial ./ from the front of the filename. You can do the equivalent with sed 's|^\./||'. The \0 part produces a null character instead of newline between each filename. You can convert newline to null with tr '\n' '\0'. So you can try

find . -mindepth 1 -print | sed 's|^\./||' | tr '\n' '\0'

If any names contain a newline, this will corrupt them, translating that newline to null and transform file paths such as ./foo<newline>./bar to foo<null>bar.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.