Copying files

I'm trying to do this exact same thing, so far I have created this to move files

i've named my script CP.sh

#!/bin/bash

cd /root/my-documents/NewDir/
for f in *.doc
do cp -v $f root/my-documents/NewDir $f{%.doc}
done

When i go to run this in the console i type, bin/sh/ CP.sh
but it comes up

bash: /bin/sh/: Not a directory
When i go to run this in the console i type, bin/sh/ CP.sh
but it comes up

Code:

bash: /bin/sh/: Not a directory

The proper command should be /bin/sh CP.sh
Notice the removal of last /
Hint: If you're testing your script that has the potential to do damage, test using echo first to see the result of what it would have been the result.

1 Like

you are missing a '/' in front of your target directory and I don't see what you are using $f{%.doc} for, is that meant to be part of the target file spec

1 Like

First: Is this a homework assignment? Homework assignments must be posted in the Homework and Coursework Forum and threads started there must include a fully completed homework template.

There are a few problems here:

  1. If you want to execute a bash run it with bash , not sh .
  2. When specifying an absolute pathname for a file; there is a / at the start of the pathname. Putting a / at the end of a pathname declares that the file named by that pathname is a directory (and if there is a file with that name that is not of type directory; it should be ignored for the purposes of resolving that pathname).
  3. Assuming that there is a file with the pathname /root/my-documents/NewDir/x.doc , one of the cp commands run by your loop would try to move the two files /root/my-documents/NewDir/x.doc and /root/my-documents/NewDir/root/my-documents/NewDir to the directory named /root/my-documents/NewDir/x .

Assuming this is not a homework assignment, your immediate problem can be solved by running the script with bash CP.sh (assuming that you have your PATH environment variable set properly) or /bin/bash CP.sh .

But, then you'll run into problems with the cp commands. If you describe what you are trying to do in English, we may be able to help you fix your code.

1 Like

So I want to copy files from one dir to another but rename the file names in the source dir to the dir name, i was attempting to create one script to copy them and another to rename them? Or is it better to do it in one? Just trying to learn Linux - its harder than I anticipated!

When I run it without the / it comes up with

cp: cannot stat "*.doc"; No such file or directory

I have files within the source dir with the extensions doc and png

What I have at the minute, I'm not too sure its accurate;

To match with only doc and png file extensions

match ="(png|.doc)"

Chose working dir

src = '${1:-}"
dest = "{2:- /root/my-documents/NewDir/}

I'm not sure how to proceed from here, maybe with a for loop?.. and I can't really implement this either, i've got some ideas but it's just putting it together and actually getting the script to run which I find difficult.

Thanks

This is the part I am missing and I quite do not understand.
Could you post an actual real example of just two files and the names you would like them to be?

Side note:

match ="(png|.doc)"

There's syntax errors on that
No spaces around the `=' , no alternate regex `|'

I could be

match=( *.png *.doc )

Here's a taste of the result of it:

[aia@ludus temp]$ match=( *.png *.doc )
[aia@ludus temp]$ echo ${#match[@]}
6
[aia@ludus temp]$ for ((i=0; i<${#match[@]}; i++)); do echo ${match}; done
file1.png
file2.png
file3.png
file1.doc
file2.doc
file3.doc

By the way, you need neither of it to do what you are trying to do.

src = '${1:-}"
dest = "{2:- /root/my-documents/NewDir/}

There are syntax errors as well. Assignment requires no spaces. Quotes must be the same, mixing ' and " are not valid. Missing one is neither valid.

1 Like

So i've managed to get the files moved and renamed however i'm finding errors when I try to put sequential numbers after the file names, my aim would be to split these up i.e sequential numbers after each file name for each file individual file type. This is my attempt;

num = 1
for f in *.png *.doc
do
cp -v $f $d "$(printf "%u" $num) . png"
let num=num+1
done

Any tips and advice are much appreciated!

Thanks again

As has been said several times before in this thread, you can't have spaces around the equal sign in a shell variable assignment.

Then you need to assign a value to the variable d (which I assume is intended to contain the pathname of your destination directory.

Assuming that you are trying to copy a single file to a new directory with a new name, you can only give two operands to cp ; not three ( $f (your source file), $d (presumably your destination directory), and "$(printf "%u" $num) . png" (which is a slow way to create a filename consisting of a number, a space, a period, a space, and the string png )).

You talked about having a base name for your files based on the final component of the pathname of your destination directory, but I don't see anything in your code that attempts to do that. There isn't anything that checks to see whether or not the calculated destination filename already exists either. Maybe you want something more like:

num=1
dp=/destination/directory/test
d=${dp##*/}
for f in *.png *.doc
do	while [ -e "$dp/$d$num.${f##*.}" ]
	do	num=$((num + 1))
	done
	cp -v "$f" "$dp/$d$num.${f##*.}"
	num=$((num+1))
done

This won't try to number .png and .doc files separately, but will verify that an existing file won't be overwritten by a new file being copied into the destination directory. (If you want separate numbering for the different file extensions, the easy way to do it would be to break the for loop into two for loops.