rsync За исключением каталога из пути назначения

Если вы не укажете имя файла в кавычках, оболочка не сможет узнать, что foo bar.txt - это один параметр, а не два ( foo и bar.txt ).Поэтому вам нужно вызвать свой сценарий следующим образом:

./chExt.sh txt ocelot.cpp ../otherFolder/file.H cat.dog.TXT "king cobra.dat"

Следующая проблема заключается в том, что при раскрытии переменных результирующее значение разбивается на пробелы (или что-то еще, что переменная $ IFS является установлен в). Итак, когда вы пишете для i в $ * , $ * расширяется и разбивается на пробелы. Следовательно, $ i становится королем для одной итерации и cobra.txt для следующей. Чтобы избежать этого, укажите переменную, которую вы хотите расширить, в кавычки, чтобы она не разделялась.

Это подводит нас к следующему вопросу - разнице между $ * и $ @ . Если вы используете «$ *» , все параметры будут обрабатываться как одна длинная строка:

$ cat foo.sh
#!/bin/sh
for i in "$*"; do
    echo "$i"
done
$ foo.sh foo "bar baz"
foo bar baz

Сравните приведенное выше с:

#!/bin/sh
for i in "$@"; do
    echo "$i"
done
$ foo.sh foo "bar baz"
foo
bar baz

Как видите, используя «$ @» имеет желаемый эффект, каждый входной параметр обрабатывается отдельно, в том числе и параметр с пробелами.

В заключение, ваш сценарий также будет подавляться именами файлов, начинающимися с - и буквой, соответствующей параметру для echo (попробуйте с файлом с именем - новый , например). Лучший способ избавиться от расширения - использовать встроенные в оболочку функции обработки строк . $ {var%. *} удаляет самую короткую строку, совпадающую с . и 0 или более символов с конца переменной. Другими словами, расширение.Затем вам также необходимо добавить - к mv , чтобы указать конец параметра и начало параметров, чтобы он также мог обрабатывать имена файлов, начинающиеся с - (см. Правило 10 здесь ).

Итак, улучшенная и рабочая версия вашего сценария будет выглядеть так:

#!/bin/sh
newExt="$1"
shift
for fileName in "$@"
do
    if test -f "$fileName";
    then
    #    name=$(echo "$fileName" | rev | cut -f 2- -d '.' | rev)
    name=${fileName%.*}
        newName="$name.$newExt"
        if test "$newName" != "$fileName";
        then
            mv -- "$fileName" "$newName"
        fi
    else
        printf '%s: No such file\n' " $fileName"
    fi
done

Дополнительная литература:

]

1
03.10.2018, 17:55
2 ответа

У вас есть 2 пути.

  1. Просто --exclude=dirи нет разницы локальная она или удаленная, так как все равно синхронизировать не хочется.
  2. Используйте --rsync-path='rsync --exclude=dir', и удаленная rsync будет выполнена с этой опцией исключения.
1
27.01.2020, 23:42

Это должно работать:

rsync -av --delete --exclude=/xyz/ sourcepath/ root@IPADDRESS:remotepath/

Это исключает "xyz", когда он встречается в корне "sourcepath", и является каталогом (, завершающий "/" гарантирует, что ).

Завершающие косые черты в исходном и целевом каталогах важны. Без этого второй запуск rsync создал бы новую папку «remotepath/sourcepath», что, вероятно, не то, что вам нужно.

Кроме того, согласно вашему описанию (у вас были неверные параметры источника и назначения, но путаница может быть моей ).

0
27.01.2020, 23:42

Теги

Похожие вопросы