How can I copy a file in a bash script and rename it while copying and place it in the same directory
31,344
Solution 1
No need for bash
here, any standard sh
interpreter implementation will do:
#! /bin/sh -
ret=0
for file do
dir=$(dirname -- "$file")
case $dir in
(*[!/]*) dir=$dir/ # handle / and // specially
esac
base=$(basename -- "$file")
name=${base%.*}
name=${name:-$base} # don't consider .bashrc the extension in /foo/.bashrc
ext=${base#"$name"}
new_file=$dir${name}_copy$ext
cp -- "$file" "$new_file" || ret=$?
done
exit "$ret"
(assumes the file and dir names don't end in newline characters).
(of course, that will also work with bash
since bash
is one of those standard sh
interpreters.)
For a bash
-specific solution, you could try:
#! /bin/bash -
ret=0
re='^((.*/)?[^/])(([^/]*)(\.))?([^/]*)/*$'
for file do
if [[ $file =~ $re ]]; then
if [[ ${BASH_REMATCH[5]} ]]; then
suffix=_copy.${BASH_REMATCH[6]}
else
suffix=${BASH_REMATCH[6]}_copy
fi
cp -- "$file" "${BASH_REMATCH[1]}${BASH_REMATCH[4]}$suffix" || ret=$?
else
printf >&2 '%s\n' "$0: Error: refusing to copy $file"
ret=1
fi
done
exit "$ret"
Solution 2
Since the OP is asking for a bash solution. Here is one that does.
#!/bin/bash
if [[ ! -f $1 && $(($# != 1)) ]]; then
printf '%s\n' "Provide a filename"
exit 1
fi
inFile="$1"
fileExt="${1#*.}"
destFile="${1%.*}"
cp -- "$inFile" "${destFile}_copy.$fileExt" # As suggested, so the files that start with a dash are not ignored.
Solution 3
#!/bin/bash
ss=0
for file do
cp -fp -- "$file" "${file%.*}_copy.${file##*.}" || ss=$?
done
exit $ss
This fails if file
does not have a dot extension part. If you need that to work use Stéphane Chazelas's solution.
Related videos on Youtube
![Gilles 'SO- stop being evil'](https://i.stack.imgur.com/cFyP6.jpg?s=256&g=1)
Author by
Gilles 'SO- stop being evil'
Updated on September 18, 2022Comments
-
Gilles 'SO- stop being evil' almost 2 years
How would I copy a file "file.doc" and rename it while copying to "file_copy.doc" and place it in the same directory ?
And this only by calling the script and adding the file name in the argument:
bash launch_copyer file.doc
-
Admin about 9 yearsIf you don't insist on Bash, I think there are ready-made tools for that as well.
-
Admin over 2 yearsRename the file to what? Copy the file to where?? What if there is already a file named file_copy.doc??
-
-
Marek Zakrzewski about 9 yearsThat's not what OP asked either. What it does is just copy source file to dest file. There is a shorter step though.
cp /path/to/dir/{file.doc,file_copy.doc}
Again, the OP wan'ts to use the positional parameter$1
-
Stéphane Chazelas about 9 yearsThat will fail in a number of cases like with those arguments:
-foo-
,foo.tar.gz
,/foo/bar
,foo.d/bar.doc
. I'm not sure why you insist on the argument being a regular file or symlink to regular file, that's not part of the requirement. Error messages should be displayed on stderr. -
roaima about 9 yearsLike mine, this also seems to fail if the file has no dotted extension
-
Stéphane Chazelas about 9 years@roaima, well, it meant to address that, but there was a typo. Should work now. It also addresses things like
foo.d/bar
,foo/.bashrc
,/foo
properly which also solution don't... -
Stéphane Chazelas about 9 years@val0x00ff, more like
cp /path/to/dir/file{,_copy}.doc
here. -
Marek Zakrzewski about 9 years@StéphaneChazelas that is even shorter indeed. Good to know.
-
holasz about 9 yearsThis won't copy files starting with a dash like
-foo
as mentioned. -
roaima about 9 years@holasz fixed that. Not planning to fix dot-extension files.