On 22/11/10 18:05, Tim wrote:

I am a cli dunce so please bear with me.

Lets say I am working in the terminal screen in the following folder

m...@computer:~#/folder1/folder2/folder3/folder4/folder5 mv blah blah.........

Now I want to go back to work in folder2, what the easy command to get me back
there??

I have to move a lot of files (1 and 2) between a lot of folders and retyping
the full path everytime is wearing my keyboard out!!


All the other suggestions are excellent, but let's have some more ;)

You could use shell variables to remember the paths:

src=/folder1/folder2/folder3/folder4/folder5
dst=/folder1/folder2

Then use cd "$src" and cd "$dst" as required, or mv somefile "$dst"

(The quotes stop things breaking if the paths have spaces in them.)

Or, how about doing (in folder5):-

ls > files
vim files
(OR nano files, OR gedit files, as you prefer)

Delete the ones you don't want to move, then save the file and:

dest=/folder1/folder2; while read -r file; do mv "$file" "$dest"; done < files

(That's all on one line but it may wrap here)

That should do a move for each filename, one per line, in "files".

Another way is with find, if the files have some criteria you can define. Find has a lot of options, and can be a bit daunting, but a good pattern to remember is:-

find [<paths>] [<tests>] [<actions>]

The default path is "." and the default action is "print", so just typing "find" will recursively list files in the current directory and subdirectories.

For example,

find -mtime -1 -maxdepth 1

Will print file names of files modified more recently than 24 hours ago in this directory only (will not go into subdirectories).

There are many ways to use this.  You could do:-

find -mtime -2 -iname 'foo*' > files

To send all files modified in the last two days matching foo* to a file called "files", and then use the mechanism above.

Another way is to use the pattern:-

find <stuff> -exec <command> '{}' \;

That's a bit odd looking, but <command> gets executed for each file found, replacing '{}' with the name. For example:-

find -mtime -2 -iname 'foo*' -exec mv '{}' /folder1/folder2

(The first time, you may want to do..

find -mtime -2 -iname 'foo*' -exec echo mv '{}' /folder1/folder2

)

(You can probably stop here if this is getting too much, or have a cup of tea and come back ... )

You can also use xargs, which takes files on the standard input and executes a command, passing them as arguments to it. There are ways to control what to do if nothing is passed, or how many arguments at once the command can take. See man xargs for more.

Here's an example:-

find -mtime -2 -iname 'foo*' | xargs rm -i

This will delete all files that find matches. It's easy if you want all the files chained onto the end of the command, but you don't so you have to use another option for xargs:-

find -mtime -2 -iname 'foo*' | xargs -I '{}' mv '{}' /folder1/folder2

Here, -I specifies some arbitrary string which gets replaced with the items being fed into xargs.

There's one more strange thing you might see, and that is to avoid the fact that here files are 1 per line, but it is technically possible for a filename to contain a line break. You can make find spit things out separated with a NULL character instead, and tell xargs to expect this.

find -mtime -2 -iname 'foo*' -print0 | xargs -0 -I '{}' mv '{}' /folder1/folder2

One last bit of polish:-

find -mtime -2 -iname 'foo*' -print0 | xargs --no-run-if-empty -0 -I '{}' mv '{}' /folder1/folder2

That's probably self-explanatory.

I know the above look a bit odd at first, but I found I'd learn them one "formula" at a time and each time I needed to do something different, I'd learn a variation, and so on.

Have fun!


--
Next meeting:  Somewhere quiet, Bournemouth, ???day 2010-12-?? 20:00
Meets, Mailing list, IRC, LinkedIn, ...  http://dorset.lug.org.uk/
How to Report Bugs Effectively:  http://goo.gl/4Xue

Reply via email to