Мне удалось исправить перенаправление с помощью этой команды:
exec 2>> (tee -a $ LOG_FULL_NAME 2> & 1 | grep -v "^ + \ | ^ ++") 1> & 2
Поскольку никто другой этого не сделал, чтобы ответить на вопрос заголовка, вы можете использовать --link-dest
. Как правило, если вы хотите синхронизировать s/
с d/
с помощью rsync, но используя жесткие ссылки вместо копий, вы можете сделать:
rsync -r --link-dest="$PWD/s/" s/ d/
Что касается ваших конкретных потребностей, когда вы хотите указать файлы, а не целые каталоги, вы можете:
find. \
-iname \*foo\*pdf \
-exec bash -c '
rsync -R \
--exclude="*bar*" \
--link-dest="$PWD/$(dirname "$1")" \
"$1" \
~/path/to/dir/
' sh {} \;
Причина, по которой здесь представлен bash, заключается в возможности получить dirname
пути к файлу. --link-dest
нужен каталог, а не сам файл. Я также использую $PWD
, потому что --link-dest
относится к каталогу назначения, а не к текущему каталогу.
Это не очень похоже на работу rsync. Rsync в основном полезен для рекурсивных копий, но, очевидно, вы собираетесь копировать только обычные файлы. Единственное преимущество rsync
перед cp
в том, что он создает родительские каталоги по мере необходимости. Вместо этого вы можете сделать это с помощью небольшого сценария оболочки, вызывающего mkdir
.
find. -type f -iname '*foo*.pdf' ! -name '*bar*' \
-exec sh -c 'mkdir -p "~/path/to/dir/${0%/*}" && cp "$0" ~/path/to/dir/"$0"' {} \;
-type f
к команде find
, чтобы исключить не -обычные файлы (, например. справочники ). Используйте -xtype f
для обработки символических ссылок на обычные файлы. ! -name '*bar*'
эквивалентно параметру rsync --exclude
. sh -c '…' {}
выполняет сценарий оболочки …
с $0
, установленным на имя файла, найденное с помощью find
. mkdir -p …
создает целевой каталог и любого родителя по мере необходимости. Здесь вы можете заменить ln
на cp
, чтобы создать жесткую ссылку.
В качестве альтернативы вы можете использовать функцию zsh zmv
. В зш:
setopt extended_glob
autoload zmv
mkdir_ln () {
mkdir -p -- $2:h
ln -- $1 $2
}
zmv -p mkdir_ln '**/(#i)*foo*.pdf~**/*bar*' ~/path/to/dir/'$f'
zmv -p mkdir_ln PATTERN REPLACEMENT
вызывает mkdir_ln FILENAME REPLACEMENT
для каждого FILENAME
, который соответствует PATTERN
, при этом $f
в REPLACEMENT
заменяется на FILENAME
. mkdir -p -- $2:h
создает часть каталога $2
и любой родительский каталог по мере необходимости. **/…
рекурсивно сопоставляет файлы в подкаталогах. (#i)
запускает поиск совпадения -без учета регистра. ~**/*bar*
исключает файлы, имя которых содержит bar
. Похоже на работу дляpax
:
find. -iname '*foo*pdf' ! -name '*bar*' -print0 |
pax -0rwl ~/path/to/dir/
Если ваш pax
не поддерживает стандарт -0
, отличный от -, удалите 0
из -print0
и -0rwl
, но имейте в виду, что это не будет работать должным образом, если ваши пути к файлам содержат символ новой строки.
Если у вас нетpax
(POSIX, но не GNU ), попробуйте заменить наcpio -0pd
(GNU, но не POSIX ).