Replace slashes in a filename
Clash Royale CLAN TAG#URR8PPP
up vote
3
down vote
favorite
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?
bash shell-script
add a comment |Â
up vote
3
down vote
favorite
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?
bash shell-script
all files - from where? Add some pseudo-code
â RomanPerekhrest
Jun 14 at 15:33
Please, show us what you tried so far.
â andcoz
Jun 14 at 15:34
4
Presuming this is for something, how are you going to handle the case ofsome__really__important_file.txt
when putting things back not going into/path/to/some/really/important_file.txt
?
â DopeGhoti
Jun 14 at 15:40
2
@DopeGhoti Good point. For example Python projects might have files named__init__.py
,__main__.py
, etc.
â wjandrea
Jun 14 at 20:05
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
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?
bash shell-script
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?
bash shell-script
edited Jun 14 at 16:08
ilkkachu
47.5k668130
47.5k668130
asked Jun 14 at 15:27
David Mathers
333
333
all files - from where? Add some pseudo-code
â RomanPerekhrest
Jun 14 at 15:33
Please, show us what you tried so far.
â andcoz
Jun 14 at 15:34
4
Presuming this is for something, how are you going to handle the case ofsome__really__important_file.txt
when putting things back not going into/path/to/some/really/important_file.txt
?
â DopeGhoti
Jun 14 at 15:40
2
@DopeGhoti Good point. For example Python projects might have files named__init__.py
,__main__.py
, etc.
â wjandrea
Jun 14 at 20:05
add a comment |Â
all files - from where? Add some pseudo-code
â RomanPerekhrest
Jun 14 at 15:33
Please, show us what you tried so far.
â andcoz
Jun 14 at 15:34
4
Presuming this is for something, how are you going to handle the case ofsome__really__important_file.txt
when putting things back not going into/path/to/some/really/important_file.txt
?
â DopeGhoti
Jun 14 at 15:40
2
@DopeGhoti Good point. For example Python projects might have files named__init__.py
,__main__.py
, etc.
â wjandrea
Jun 14 at 20:05
all files - from where? Add some pseudo-code
â RomanPerekhrest
Jun 14 at 15:33
all files - from where? Add some pseudo-code
â RomanPerekhrest
Jun 14 at 15:33
Please, show us what you tried so far.
â andcoz
Jun 14 at 15:34
Please, show us what you tried so far.
â andcoz
Jun 14 at 15:34
4
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 at 15:40
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 at 15:40
2
2
@DopeGhoti Good point. For example Python projects might have files named
__init__.py
, __main__.py
, etc.â wjandrea
Jun 14 at 20:05
@DopeGhoti Good point. For example Python projects might have files named
__init__.py
, __main__.py
, etc.â wjandrea
Jun 14 at 20:05
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
-1
down vote
accepted
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
Thatfind
command will not work. The backticks will be evaluated beforefind
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 filef
in/base/path
, this will try to copy it to__home__user__/base/path/f
.
â JoL
Jun 14 at 21:04
@JoL It worked when I tested it... I'll test it again when I get a few minutes...
â Perkins
Jun 17 at 3:47
find -exec sh -c 'cp "$1" "$(realpath "$1" |ÃÂ sed s:/:__:g)"' sh ;
should do
â ilkkachu
Jun 17 at 17:18
xargs
will have issues with names with whitespace, unless you usefind -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 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 at 3:16
 |Â
show 2 more comments
up vote
9
down vote
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////__
add a comment |Â
up vote
6
down vote
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.
add a comment |Â
up vote
0
down vote
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
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
-1
down vote
accepted
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
Thatfind
command will not work. The backticks will be evaluated beforefind
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 filef
in/base/path
, this will try to copy it to__home__user__/base/path/f
.
â JoL
Jun 14 at 21:04
@JoL It worked when I tested it... I'll test it again when I get a few minutes...
â Perkins
Jun 17 at 3:47
find -exec sh -c 'cp "$1" "$(realpath "$1" |ÃÂ sed s:/:__:g)"' sh ;
should do
â ilkkachu
Jun 17 at 17:18
xargs
will have issues with names with whitespace, unless you usefind -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 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 at 3:16
 |Â
show 2 more comments
up vote
-1
down vote
accepted
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
Thatfind
command will not work. The backticks will be evaluated beforefind
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 filef
in/base/path
, this will try to copy it to__home__user__/base/path/f
.
â JoL
Jun 14 at 21:04
@JoL It worked when I tested it... I'll test it again when I get a few minutes...
â Perkins
Jun 17 at 3:47
find -exec sh -c 'cp "$1" "$(realpath "$1" |ÃÂ sed s:/:__:g)"' sh ;
should do
â ilkkachu
Jun 17 at 17:18
xargs
will have issues with names with whitespace, unless you usefind -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 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 at 3:16
 |Â
show 2 more comments
up vote
-1
down vote
accepted
up vote
-1
down vote
accepted
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
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
edited Jun 18 at 17:47
answered Jun 14 at 18:10
Perkins
24515
24515
5
Thatfind
command will not work. The backticks will be evaluated beforefind
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 filef
in/base/path
, this will try to copy it to__home__user__/base/path/f
.
â JoL
Jun 14 at 21:04
@JoL It worked when I tested it... I'll test it again when I get a few minutes...
â Perkins
Jun 17 at 3:47
find -exec sh -c 'cp "$1" "$(realpath "$1" |ÃÂ sed s:/:__:g)"' sh ;
should do
â ilkkachu
Jun 17 at 17:18
xargs
will have issues with names with whitespace, unless you usefind -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 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 at 3:16
 |Â
show 2 more comments
5
Thatfind
command will not work. The backticks will be evaluated beforefind
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 filef
in/base/path
, this will try to copy it to__home__user__/base/path/f
.
â JoL
Jun 14 at 21:04
@JoL It worked when I tested it... I'll test it again when I get a few minutes...
â Perkins
Jun 17 at 3:47
find -exec sh -c 'cp "$1" "$(realpath "$1" |ÃÂ sed s:/:__:g)"' sh ;
should do
â ilkkachu
Jun 17 at 17:18
xargs
will have issues with names with whitespace, unless you usefind -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 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 at 3:16
5
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 at 21:04
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 at 21:04
@JoL It worked when I tested it... I'll test it again when I get a few minutes...
â Perkins
Jun 17 at 3:47
@JoL It worked when I tested it... I'll test it again when I get a few minutes...
â Perkins
Jun 17 at 3:47
find -exec sh -c 'cp "$1" "$(realpath "$1" |ÃÂ sed s:/:__:g)"' sh ;
should doâ ilkkachu
Jun 17 at 17:18
find -exec sh -c 'cp "$1" "$(realpath "$1" |ÃÂ sed s:/:__:g)"' sh ;
should doâ ilkkachu
Jun 17 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 at 17:22
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 at 17:22
1
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 at 3:16
@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 at 3:16
 |Â
show 2 more comments
up vote
9
down vote
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////__
add a comment |Â
up vote
9
down vote
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////__
add a comment |Â
up vote
9
down vote
up vote
9
down vote
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////__
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////__
edited Jun 14 at 16:06
ilkkachu
47.5k668130
47.5k668130
answered Jun 14 at 15:36
DSX
514
514
add a comment |Â
add a comment |Â
up vote
6
down vote
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.
add a comment |Â
up vote
6
down vote
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.
add a comment |Â
up vote
6
down vote
up vote
6
down vote
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.
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.
edited Jun 14 at 15:44
answered Jun 14 at 15:36
Jesse_b
10.2k22658
10.2k22658
add a comment |Â
add a comment |Â
up vote
0
down vote
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
add a comment |Â
up vote
0
down vote
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
add a comment |Â
up vote
0
down vote
up vote
0
down vote
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
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
answered Jun 15 at 3:01
Praveen Kumar BS
1,010128
1,010128
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f449841%2freplace-slashes-in-a-filename%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
all files - from where? Add some pseudo-code
â RomanPerekhrest
Jun 14 at 15:33
Please, show us what you tried so far.
â andcoz
Jun 14 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 at 15:40
2
@DopeGhoti Good point. For example Python projects might have files named
__init__.py
,__main__.py
, etc.â wjandrea
Jun 14 at 20:05