Этот скрипт должен делать то, что вы хотите. Это немного сложнее, чем вы могли бы ожидать, потому что он должен иметь возможность работать с произвольными именами файлов и каталогов. Включая имена с символами новой строки, пробелами и символами. Это должно работать с любым именем, которое вы ему дадите.
#!/usr/bin/env bash
sourceDir="$1"
targetDir="."
## The name of the source directory without its path
## First, we need to strip the trailing `/` if present.
sourceDir="${sourceDir%/}"
sourceName="${sourceDir##*/}"
## Find all files and directories in $source. -print0
## is needed to deal with names with newlines
find "$sourceDir" -mindepth 1 -print0 |
## Read eacch file/dir found into $f. IFS= ensures
## we can deal with whitespace correctly and -d ''
## lets 'read' read null-separated values. The -r
## ensures that backspaces don't have special meaning. All
## this to be certain that this will work on arbitrary file names.
while IFS= read -r -d '' f; do
##
name="${f##$sourceDir}"
## Build the relative path for the symlink
relname=$(perl -le '$ARGV[0]=~s|/[^/]+|/..|g;
$ARGV[0]=~s|../..$|$ARGV[1]/$ARGV[2]|;
print $ARGV[0]' "$f" "$sourceName" "$name")
## If this is a directory, create it
if [ -d "$f" ]; then
mkdir -p "$targetDir/$name"
## If a file, link to it.
else
ln -s "$relname" "$targetDir/$name"
fi
done
Сохраните сценарий и сделайте его исполняемым, а затем cd
в ваш целевой каталог и перейдите в сценарий с исходным каталогом в качестве аргумента. Например, чтобы продублировать каталог ../target
в текущем каталоге, вы должны выполнить:
foo.sh ../target/