So here's current path:


here end goal:


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
  • @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. Jan 1, 2017 at 21:47
  • 2
    @roaima Looks like it's the same person; I put in a merge request Jan 1, 2017 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, 2017 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 Jan 2, 2017 at 8:48

2 Answers 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' \;
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


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' \;
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


-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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .