0

I'm using csh and I have a directory structure containing multiple sub-directories. I'm trying to rename all the directories and sub-directories but not the files inside these directories. So something like

From

topdir1
--dir11
--dir12
topdir2
--dir21
----dir211
--dir22

to

topdir1.test
--dir11.test
--dir12.test
topdir2.test
--dir21.test
----dir211.test
--dir22.test

I can list the directories with find . -maxdepth 3 -type d. I'm trying to use a foreach loop to rename them. So

foreach i (`find . -maxdepth 3 -type d`)
mv $i $i.test
end

But this doesn't work as once the top level directory is renamed, it cannot find the sub-directories, so it only renames the top level directories.

Any idea on how to go about this?

Thanks

3 Answers3

2

How about reversing the find results so that the subdirectories are listed first?

foreach i (`find ./* -maxdepth 3 -type d | sort -r`)
mv $i $i.test
end

Sort will output the longest directory names last, using the -r (reverse) flag changes it so that the lowest directories will be listed first, and be renamed before their parent directories do.

Josh Jolly
  • 11,258
  • 2
  • 39
  • 55
1

Use the -depth option to find.

From the solaris man find page:

 -depth              Always  true.  Causes  descent  of   the
                     directory  hierarchy  to be done so that
                     all entries in a directory are acted  on
                     before  the  directory itself.  This can
                     be useful when find is used with cpio(1)
                     to  transfer files that are contained in
                     directories without write permission.
rojomoke
  • 3,765
  • 2
  • 21
  • 30
  • Not just from the Solaris man page. This is standard: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html#tag_20_47 – William Pursell Feb 04 '14 at 16:53
0

Why use a loop? Just let find do the work:

find . -depth -maxdepth 3 -type d -exec mv {} {}.test \;

That is not strictly portable (some implementations of find may legally not expand {}.test to the string you want, so you might prefer:

find . -depth -maxdepth 3 -type d -exec sh -c 'mv $0 $0.test' {} \;
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • I use a loop so that the directory structure is not changed, just the directory names. This doesn't work as puts all the renamed directories and sub-directories into .test/ – user3271385 Feb 04 '14 at 17:03
  • No, it renames the directories in the tree in the same way as your loop. `{}` expands to the relative path, not the basename. – William Pursell Feb 04 '14 at 17:17