3

Ok, this is my third try posting this, maybe I'm asking the wrong question!!

It's been a few years since I've done any shell programming so I'm a bit rusty...

I'm trying to create a simple shell script that finds all subdirectories under a certain named subdirectory in a tree and creates symbolic links to those directories (sounds more confusing than it is). I'm using cygwin on Windows XP.

This find/grep command finds the directories in the filesystem like I want it to:

find -mindepth 3 -maxdepth 3 -type d | grep "New Parts"

Now for the hard part... I just want to take that list, pipe it into ln and create some symlinks. The list of directories has some whitespace, so I was trying to use xargs to clean things up a bit:

find -mindepth 3 -maxdepth 3 -type d | grep "New Parts" | xargs -0 ln -s -t /cygdrive/c/Views

Unfortunately, ln spits out a long list of all the directories concatenated together (seperated by \n) and spits out a "File name too long" error.

Ideas??

seth
  • 36,759
  • 7
  • 60
  • 57

3 Answers3

4

I think you can do this all within your find command. OTTOMH:

find -mindepth 3 -maxdepth 3 -type d -name "*New Parts*" -exec ln -s -t /cygdrive/c/Views {} \;

Hope I remembered that syntax right.

NWCoder
  • 5,296
  • 1
  • 26
  • 23
  • 1
    +1 for the -exec flag. People seem to forget this one a lot. You might want to enclose the {} in quotes though so it handles names with spaces in them ok. – Jeremy Wall Aug 27 '09 at 02:56
1

your command

find -mindepth 3 -maxdepth 3 -type d | grep "New Parts" | xargs -0 ln -s -t /cygdrive/c/Views

have argument "-0" to xargs but you did not tell find to "-print0" (if you did grep could not work in the pipe inbetween). What you want is the following I guess:

find -mindepth 3 -maxdepth 3 -type d | grep "New Parts" | tr '\012' '\000' | xargs -0 ln -s -t /cygdrive/c/Views

The tr command will convert newlines to ascii null.

hlovdal
  • 26,565
  • 10
  • 94
  • 165
1

Use a for loop.

for name in $(find $from_dir -mindepth 3 -maxdepth 3 -type d); do
  ln -s $name $to_dir
done

Xargs has issues where the input from the pipe goes at the end of the command. What you want is multiple commands, not just 1 command.

My experience with doing things within the find command can sometimes be slow, although it does get the job done.

KFro
  • 764
  • 3
  • 8
  • Your command will fail if one of the directories found contains spaces. You must add quotes, i.e. <>. That is one of the great benefits of using "xargs -0" that you avoid all such issues. – hlovdal Aug 25 '09 at 22:02