9

Using Bash

So let's say I have a bunch of files randomly placed in a parent directory ~/src, I want to grab all the files matching a certain suffix and move (or copy) them to a ~/dist directory.

Let's assume for this purpose that all filenames have this naming convention:

<filename_prefix>.<filename_suffix>

I found out that this was a quick way to get all files with a particular filename_suffix and put them in a dist folder:

mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;

Now a step further... how can I use the output of find, in this case filename, and use the filename_prefix to generate a directory of the same name in ~/dist and then move (or copy) all the files with that prefix into the appropriate directory?

mkdir ~/dst
find source -name "*.xrt,*.ini,*.moo" -exec mv -i {} -t ~/dst \;

Essentially, how do I change the above command (or maybe use another command), to create a structure like this

(OUTPUT)

~/dist/people/people.xrt
~/dist/games/games.xrt
~/dist/games/games.moo
~/dist/games/games.ini
~/dist/monkeys/monkeys.ini
~/dist/monkeys/monkeys.xrt

from a directory tree like this?

(INPUT)

~/src/xrt/people.xrt
~/src/xrt/games.xrt
~/src/conf/games.ini
~/src/pack/monkeys.xrt
~/src/e344/games.moo
~/src/e344/monkeys.moo
~/src/en-us/monkeys.ini
10

It would be a hell to tell find what to do in this case.

Better use the shell:

for i in **/*.{xrt,ini,moo}; do
  FILE=$(basename "$i")
  DIR=~/dst/${FILE%.*}
  echo mkdir -p -- "$DIR"
  echo mv -i -t "$DIR" -- "$i"
done

Use shopt -s globstar to make the ** glob work (or use zsh!). And remove the echos later if the command prints what you want.

  • using bash is this the same? – qodeninja Feb 6 '12 at 20:44
  • @codeninja shopt -s globstar, see my edit. If there are only two levels, you can use */*.* and the snippet will work in any shell. – Gilles Feb 7 '12 at 0:40
2

cheating find command line:

find source -name "*.xrt,*.ini,*.moo" -exec env file={} bash -c 'base="$(basename "$file")";dir="dst/${base%.*}";mkdir -p "$dir";cp "$file" "$dir"' \;

actually a work around for calling bash script in find LOL.

=P

  • 1
    Guess what happens if there is a file which is called… happy rm -rf / ! This kind of code deserves a -1. – Stéphane Gimenez Feb 7 '12 at 13:04
  • Your edit is not enough: let's say you cliked on a link and downloaded Yay" rm -rf / "Rox0r.avi, again there is like a problem… – Stéphane Gimenez Feb 7 '12 at 13:22
  • (And there is no way to make this kind of substitution safe). – Stéphane Gimenez Feb 7 '12 at 13:24
  • 1
    Ah maybe it's possible to do this differently. It seems that the following works: -exec bash -c 'command which uses "$1"' bash '{}' ';'. Well, it's quite pointless anyway. – Stéphane Gimenez Feb 7 '12 at 13:26
  • 1
    @StéphaneGimenez done, bash is not the only thing to use. LOL – yuyichao Feb 7 '12 at 13:30

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.