7

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
  • If you don't insist on Bash, I think there are ready-made tools for that as well. – 0xC0000022L May 19 '15 at 15:18
  • Maybe it's just me, but I find the wording really confusing here. Why are mv and cp insufficient? Could we have an example? – Anko May 19 '15 at 19:20
4

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"
  • Like mine, this also seems to fail if the file has no dotted extension – roaima May 19 '15 at 16:08
  • 1
    @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 May 19 '15 at 16:20
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.
  • 1
    That 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. – Stéphane Chazelas May 19 '15 at 14:44
  • 1
    @StéphaneChazelas You've a point there. I should have used -- to indicate end of options. Well the .doc suggests a file. That check is not necessarily either. – Valentin Bajrami May 19 '15 at 14:51
  • @StéphaneChazelas that is even shorter indeed. Good to know. – Valentin Bajrami May 19 '15 at 21:14
1
#!/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.

  • This won't copy files starting with a dash like -foo as mentioned. – holasz May 20 '15 at 8:29
  • @holasz fixed that. Not planning to fix dot-extension files. – roaima May 20 '15 at 8:53
0
cp /example/directory/file.doc /example/directory/file_copy.doc

this specifies the file name and will do what you want

  • That'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 – Valentin Bajrami May 19 '15 at 14:22
  • @val0x00ff, more like cp /path/to/dir/file{,_copy}.doc here. – Stéphane Chazelas May 19 '15 at 16:31
0

Try this:

#!/bin/bash
if [ -f "$1" ];
then
  cp -v "$1" _"$1"
  rename -v 's/_(.+?)\./$1_copy\./' _"$1"
fi

The script checks if the input file that receives as input exists. In that case, it makes a temporary copy of the file and then renames such copy replacing the first dot in its name with the string _copy.

I hope it is what you needed.

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.