Копирование файлов в конвейере с использованием шеллскрипта cygwin bash

296
Stumac

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

потому что я cat boards делаю ls -t $ work | grep ^ $ i | cp .............

Если я запускаю только с помощью grep, он перечисляет все файлы, которые я хочу, но я не знаю, как получить это на cp cmnd.

Давным-давно я делал все это, но, похоже, помнил, что существует автоматическая переменная, содержащая входные данные из stdin. Любая помощь приветствуется.

2

2 ответа на вопрос

1
Peter Berbec

Похоже, вы охотитесь за Xargs .

destination="/path/to/folder" for i in $(cat boards) do  ls -t $work | grep ^$i | xargs -Isource cp source /path/to/destination done 

Запустите forцикл, используя переменную, iзаполненную результатами cat boards( $()порождает процесс).

xargs -Isourceпринимает вывод grep ^$iи кормит его cpв sourceположении cp source /path/to/destination. Со страницы руководства:

-I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input.

Надеюсь, это было то, что вы искали.

1
minnmass

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

Похоже, вы хотите, чтобы все файлы в / path / to / $ работали, где имя файла начинается со строки из файла board, которая будет скопирована в какой-либо пункт назначения.

например, дано

$ cat boards start1 start2 $ ls $work start1.txt start1.jpg start2.txt start2.jpg start3.txt $ 

Вы хотите, чтобы start1.txt, start1.jpg, start2.txt и start2.jpg были скопированы куда-либо, но не start3.txt.

Не используйте xargs: это фантастический инструмент, но он будет вызывать проблемы, если в любом из ваших файлов или «шаблонов поиска» будут пробелы или символы глобуса (например, «*»).

Скорее используйте инструмент, который ожидает шаблон поиска, найти .

cat boards | while read pattern find $work -name "$*" -exec cp {} /path/to/destination + done 

Это будет читать в каждой строке boardsкак шаблон поиска. findзатем загляните в $workкаталог, чтобы найти файлы (и папки!), которые соответствуют $*; каждый найденный элемент (файл или папка) будет передан в cp как должным образом экранированный параметр (на {}месте), и он будет делать, xargsкак минимизация количества cpпроцессов, которые он запускает из-за +(если вы хотели, чтобы только один процесс на найденный предмет, вы бы ;вместо этого использовали - обязательно избегайте его как следует).

findимеет богатый набор фильтров, которые вы можете применить, чтобы сузить область поиска. Особого внимания заслуживает -type fопция, которая ограничивает результаты в файле.

Обратите внимание, что cpкоманда может завершиться ошибкой, если в списке аргументов переданы папки find; использование -type fфильтра предотвратит это.

Также обратите внимание, что cpкоманда «сгладит» выходной каталог - если $workесть подкаталоги, в которых есть совпадающие файлы, эти файлы будут скопированы прямо /path/to/destination. Если вы хотите копировать файлы только на верхнем уровне $work, -maxdepthфильтр (вероятно, со значением 1 :) -maxdepth 1предотвратит findповторное копирование слишком глубоко в файловой системе.

Обратите внимание, что findэто с учетом регистра. Если вы не хотите, чтобы это было, вы можете использовать -inameвместо выполнения -nameпоиска без учета регистра.

Если есть какие-либо другие параметры командной строки, которые вы хотите задать cp, просто поместите их перед {}(например, cp -r {}для копирования каталогов, которые соответствуют шаблону поиска).

Хороший вопрос о странных именах файлов. Существует решение в обоих направлениях, но IFS = и -print0 становятся ужасными. Потенциальная настройка вашего поиска, возможно, используйте `-exec cp" {} "`, чтобы перехватить неизбежные пробелы? Peter Berbec 6 лет назад 0
{} Уже обрабатывает это; цитирование их просто отправит буквально пару фигурных скобок в cp, который будет жаловаться на отсутствие такого файла. minnmass 6 лет назад 1
Только что проверил, и мы оба правы! :) Голые скобки прекрасно работают даже с именами файлов, включая пробел, как и двойные кавычки (`" {} "`). То, как я думал, не сработает, использование одинарных скобок (`'{}'`) также работает нормально. Я предполагал, что одинарные кавычки передали бы скобки в качестве аргументов, но я думаю, что нет. Выход из скобок завершается успешно. Выход из любой цитаты заканчивается неудачей. Выход из фигурных скобок внутри кавычек любого типа завершается неудачно с помощью `not stat" \ {\} "`. Выход из кавычек с экранированными скобками завершается неудачно, когда `` stat "не указывается с именем файла, как если бы оно начиналось с кавычек Peter Berbec 6 лет назад 1
глубокий; curlies - это аргументы для поиска, поэтому, конечно, цитирование их будет работать. Извините, у меня там был тупой. minnmass 6 лет назад 0
Нет, мой тупой Я не знал, что керли сбежал должным образом. Peter Berbec 6 лет назад 0

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