Как исключить определенный файл в команде оболочки scp linux? - PullRequest
1 голос
/ 27 июня 2019

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

Например, в исходной папке у меня есть четыре файла:

file1.csv, file2.csv, file3.csv, file4.csv

Из этих четырех файлов я хочу скопировать все файлы, кроме file4.csv, в расположение приемника.

Когда я использовал приведенную ниже команду scp:

scp /tmp/source/*.csv /tmp/sink/

Это скопировало бы все четыре CSV-файла в местоположение приемника.

Как мне добиться того же, используя команду scp или написав сценарий оболочки?

Ответы [ 4 ]

5 голосов
/ 27 июня 2019

Вы можете использовать rsync с переключателем --exclude, например,

rsync /tmp/source/*.csv /tmp/sink/ --exclude file4.csv
4 голосов
/ 27 июня 2019

Bash имеет расширенную функцию , которая позволяет это делать.Во многих случаях вам необходимо отдельно включить эту функцию с помощью

shopt -e extglob

. Имея эту возможность, вы можете

scp tmp/source/(!fnord*).csv /tmp/sink/

скопировать все *.csv файлы, кроме fnord.csv.

Это особенность оболочки;оболочка расширит глобус до списка подходящих файлов - scp не будет знать, как был создан этот список аргументов.

1 голос
/ 27 июня 2019

Как уже упоминалось в вашем комментарии , rsync не подходит для вас.Решение, представленное tripleee , работает, только если источник находится на стороне клиента.Здесь я представляю решение, используя ssh и tartar есть флаг --exclude, который позволяет исключать шаблоны:

от сервера к клиенту:

$ ssh user@server 'tar -cf - --exclude "file4.csv" /path/to/dir/*csv' \
  | tar -xf - --transform='s#.*/##' -C /path/to/destination

По сути, это создает таргетшарик, который посылается через /dev/stdout, который мы отправляем в гудрон.Для имитации scp нам нужно удалить полный путь, используя --transform (см. U & L ).При желании вы можете добавить каталог назначения.

от клиента к серверу:

Мы делаем по сути то же самое, но меняем роли:

$ tar -cf - --exclude "file4.csv" /path/to/dir/*csv \
  | ssh user@server 'tar -xf - --transform="s#.*/##" -C /path/to/destination'
0 голосов
/ 27 июня 2019

Вы можете использовать массив bash для сбора большего набора, а затем удалять ненужные элементы. Например:

files=( /tmp/src/*.csv )
for i in "${!files[@]}"; do
  [[ ${files[$i]} = *file4.csv ]] && unset files[$i]
done
scp "${files[@]}" host:/tmp/sink/

Обратите внимание, что наш цикл for выполняет индекс массива, а не значения, поэтому у нас будет правильный ввод для команды unset, если она нам понадобится.

...