Flatten a folder structure to a file name in Bash

This might work for you:

find . -type f -name "*.png" | sed 'h;y/\//_/;H;g;s/\n/ /g;s/^/cp -v /' | sh

find -type f -name '*.png' -printf '%P\0' | \
while read -d $'\0' i ; do cp "$i" "${i////_}" ; done

Where:

  • %P tell find to omit the leading ./;

  • \0 tell find to print the paths using the ASCII NUL character as separator (this should avoid problems with strange names);

  • -d $'\0' tell bash to use the proper delimiter for reading the paths;

  • ${i////_} tell bash to replace every occurrences of / with _ in the path.

Warning:

This pipeline may involve file overwrites, make sure to take the proper precautions.

Tags:

Bash

Find

Sed