1

Я хотел бы сделать ссылки на все файлы в дереве каталогов. Это означает, что создайте ту же структуру каталогов и создайте в них ссылки на соответствующий подкаталог в исходном каталоге.

Это может быть сделано с

cp -R -s ../foo .

Но - для этого нужен абсолютный путь. Так скорее

cp -R -s `readlink -e ../foo` `readlink -e .`

Я хотел бы, чтобы полученные ссылки были относительными.

Есть ли какой-нибудь простой способ? Например, какой-нибудь скрипт или программа, специально для этого.

1 ответ1

0

Этот скрипт должен делать то, что вы хотите. Это немного сложнее, чем вы могли бы ожидать, потому что он должен иметь возможность работать с произвольными именами файлов и каталогов. Включая имена с символами новой строки, пробелами и символами. Это должно работать с любым именем, которое вы ему дадите.

#!/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/

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .