2

So here's current path:

../CAMERA3/serialnum/2016-12-19/001/dav/07/07.02.53-07.03.14[M][0@0][0].dav

here end goal:

../CAMERA3/2016-12-19_07.02.53-07.03.14.dav

So I'm basically trying to figure out a for loop that pulls some of the directory names and portion of filename like so:

mv ../$dir1/$dir2/$dir3/$dir4/$dir5/$dir6/$filenameportion[M][0@0][0].dav ../$dir1/$dir3_$filenameportion.dav
4
  • @user208086 are you the same user as Paul? If not how can you know that \ should be replaced by /? If you are, please consider merging your accounts. – roaima Jan 1 '17 at 21:47
  • 2
    @roaima Looks like it's the same person; I put in a merge request – Michael Mrozek Jan 1 '17 at 22:35
  • @MichaelMrozek Should the edit reviewers also make a merge request in such cases where it's very likely the same person? And how? Mod intervention flag? – phk Jan 2 '17 at 1:28
  • 1
    @phk Mod flag saying "I think these are the same person" works; we can check some things to make sure it really is and forward the flag to the Stack Exchange community team to do the merge – Michael Mrozek Jan 2 '17 at 8:48
2

Ended up having to use rnm. Kind of ugly but it works:

find /mnt/test -name '*.dav' -exec sh -c 'for filename do 
    if [[ $(basename "$filename") != C*.dav ]];then
        find "$filename" -type f -execdir ~/bin/rnm -y "$filename" -ns '/pd05/_/pd03/_/n/.dav' \;
    fi
done' find-sh {} \;

find /mnt/test -name '*.dav' -exec sh -c 'for filename do 
    rename "[M][0@0][0]" "" "$filename" 
done' find-sh {} \;

find /mnt/test -name '*.dav' -type f -execdir sh -c 'mv "$@" ./../../../../..' find-sh {} \;

PS: Yes I'm both users. I originally posted as guest and then followed the email link to create an account. Surprised it wasn't automatic. Sorry about backslashes confusion, copied files to windows laptop, forgot to change back for post.

Update 1: removed looping over finds output

5
0

Improving Pauls' answer:

The following code:

find /mnt/test -name '*.dav' -exec sh -c 'for filename do 
    if [[ $(basename "$filename") != C*.dav ]];then
        find "$filename" -type f -execdir ~/bin/rnm -y "$filename" -ns '/pd05/_/pd03/_/n/.dav' \;
    fi
done' find-sh {} \;

Can be optimized like this (without any find or for loop):

rnm -y -ns '/pd5/_/pd3/_/n/.dav' -ss '^[^C].*\.dav$' -fo -dp -1 /mnt/test

Explanation:

-ss: Search string (regex). The regex used above searches for files that end with .dav and do not start with C.

-fo: File only mode.

-dp: Depth. -1 means unlimited depth i.e go to all subdirectories.

-ns: Name string (new name)

/pd<digit>/: A name string rule that implies different levels of parent directory names: 0 is the immediate parent, 1 is above that and so forth.

/n/: Another name string rule that implies file name without extension. /n/.dav could be replaced with /fn/ (full name).

-y: Confirm (--yes) for all.

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.