Replace slashes in a filename

To get the path of your file :

realpath <file>

Replace in bash:

echo "${var//search/replace}"

The first two slashes are for making global search. Using just / would only do one replacement.

So your code could be

path=$(realpath zad1.sh)
path_replaced=${path//\//__}

I believe this will accomplish what you are asking:

#!/bin/bash

_from_dir=/path/to/files
_to_dir=/path/to/dest

for file in "${_from_dir}/"*; do
    nfile="$(sed 's#/#__#g' <<<"$file")"
    cp "$file" "${_to_dir}/$nfile"
done

Set the _from_dir variable to the path where your files are located and the _to_dir variable to the path where you want them copied.

The loop will go through each file in the _from_dir location. nfile will take the full path of the file and replace / with __. Then it will cp the file into the _to_dir path with a name representing the full path of it's origin.


The classic approach would be to use sed:

cp "${filename}" "$(realpath ${filename} | sed s:/:__:g)"

The advantage is primarily portability across shells if you won't necessarily always be using bash.

Of course, it also lets you forego the script and just do it with find:

find /base/path -type f -exec cp \{\} `realpath \{\} | sed s:/:__:g` \;

Find has sorting and filtering options you can use if you need them to only copy certain files.

edit: That find setup works on one of my systems, but not on the other one. Rather than sort out the difference, I just made it more portable:

find /base/path -type f | sed -e "p; s:/:__:g" | xargs -n2 cp