Frage

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

War es hilfreich?

Lösung

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.

Andere Tipps

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.

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' {} \;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top