So I need to write a bash script that copies all files to a specified directory however I need to rename the files to it's absolute path by replacing the / character with __.

For example if the file zad1.sh is in the directory /home/123456/ the file needs to be renamed to __home__123456__zad1.sh

Any ideas on how to do this?

  • all files - from where? Add some pseudo-code Jun 14, 2018 at 15:33
  • Please, show us what you tried so far.
    – andcoz
    Jun 14, 2018 at 15:34
  • 4
    Presuming this is for something, how are you going to handle the case of some__really__important_file.txt when putting things back not going into /path/to/some/really/important_file.txt?
    – DopeGhoti
    Jun 14, 2018 at 15:40
  • 2
    @DopeGhoti Good point. For example Python projects might have files named __init__.py, __main__.py, etc.
    – wjandrea
    Jun 14, 2018 at 20:05

4 Answers 4


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)

I believe this will accomplish what you are asking:



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

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
  • 5
    That find command will not work. The backticks will be evaluated before find and get you basically the equivalent of $PWD/{} with the slashes in $PWD replaced with double underscores. So, if you're in /home/user, this is equivalent to: find /base/path -exec cp {} __home__user__{} \; If you have a file f in /base/path, this will try to copy it to __home__user__/base/path/f.
    – JoL
    Jun 14, 2018 at 21:04
  • @JoL It worked when I tested it... I'll test it again when I get a few minutes...
    – Perkins
    Jun 17, 2018 at 3:47
  • find -exec sh -c 'cp "$1" "$(realpath "$1" | sed s:/:__:g)"' sh {} \; should do
    – ilkkachu
    Jun 17, 2018 at 17:18
  • xargs will have issues with names with whitespace, unless you use find -print0 | sed -z | xargs -0 (with at least GNU sed). Also any of those will make the copies to the current directory, which may or may not be what you want.
    – ilkkachu
    Jun 17, 2018 at 17:22
  • 1
    @Perkins "That find setup works on one of my systems" I have a hard time imagining how that could work anywhere. The only edge case I can kind of see is if your current working directory is /base/path and you just have regular files in there, no directories. However, even then you'd be copying to e.g. /base/path/__base__path__./f. That's not right.
    – JoL
    Jun 18, 2018 at 3:16

I have done by below method

ls -ltr /root/l.txt| awk '{print "cp" " " $NF,$NF}'| awk '{gsub("/","_",$NF);print $1,$2,"/root/p1/"$3}'| sh

Here file /root/l.txt will be copied to /root/p1/ path but filename will be _root_l.txt Let me know for any confusion

Here /root/p1==> destination path

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.