У вас должна быть возможность использовать -execdir
для создания копии относительно каталога найденного файла (ов), например.
find Italy -name '*.front.*' -execdir cp -- {} 'fanart.jpg' \;
Пример: given
$ tree Italy/
Italy/
├── Florence
│ ├── photo.back.001.jpg
│ ├── photo.back.002.jpg
│ ├── photo.back.003.jpg
│ ├── photo.front.001.jpg
│ ├── photo.front.002.jpg
│ └── photo.front.003.jpg
├── Naples
│ ├── photo.back.001.jpg
│ ├── photo.back.002.jpg
│ ├── photo.back.003.jpg
│ ├── photo.front.001.jpg
│ ├── photo.front.002.jpg
│ └── photo.front.003.jpg
└── Rome
├── photo.back.001.jpg
├── photo.back.002.jpg
├── photo.back.003.jpg
├── photo.front.001.jpg
├── photo.front.002.jpg
└── photo.front.003.jpg
3 directories, 18 files
Затем
$ find Italy -name '*.front.*' -execdir cp -v -- {} 'fanart.jpg' \;
‘./photo.front.001.jpg’ -> ‘fanart.jpg’
‘./photo.front.003.jpg’ -> ‘fanart.jpg’
‘./photo.front.002.jpg’ -> ‘fanart.jpg’
‘./photo.front.001.jpg’ -> ‘fanart.jpg’
‘./photo.front.003.jpg’ -> ‘fanart.jpg’
‘./photo.front.002.jpg’ -> ‘fanart.jpg’
‘./photo.front.001.jpg’ -> ‘fanart.jpg’
‘./photo.front.003.jpg’ -> ‘fanart.jpg’
‘./photo.front.002.jpg’ -> ‘fanart.jpg’
(обратите внимание, что если есть несколько файлов, соответствующих шаблону *. Front. *
, копия последовательно перезаписывается - если это не то, что вы хотите, добавьте -n
или - no-clobber
), что приводит к
$ tree Italy/
Italy/
├── Florence
│ ├── fanart.jpg
│ ├── photo.back.001.jpg
│ ├── photo.back.002.jpg
│ ├── photo.back.003.jpg
│ ├── photo.front.001.jpg
│ ├── photo.front.002.jpg
│ └── photo.front.003.jpg
├── Naples
│ ├── fanart.jpg
│ ├── photo.back.001.jpg
│ ├── photo.back.002.jpg
│ ├── photo.back.003.jpg
│ ├── photo.front.001.jpg
│ ├── photo.front.002.jpg
│ └── photo.front.003.jpg
└── Rome
├── fanart.jpg
├── photo.back.001.jpg
├── photo.back.002.jpg
├── photo.back.003.jpg
├── photo.front.001.jpg
├── photo.front.002.jpg
└── photo.front.003.jpg
Если версия в вашей системе, find
не поддерживает -execdir
альтернативным способом было бы удалить часть имени файла из полного имени пути - например, используя расширение параметра POSIX в форме «$ {var% / *}»
- и немного заменить его новым именем встроенная команда оболочки sh -c
find Italy -name '*.front.*' -exec sh -c 'cp -v -- "$1" "${1%/*}/fanart.jpg"' sh {} \;
Это расширение OSX sed
, а не стандартное поведение. Вы можете увидеть эту ссылку в функции compile_text
:
/*
* Compile the text following an a or i command.
*/
static char *
compile_text()
{
int asize, size;
char *text, *p, *op, *s;
char lbuf[_POSIX2_LINE_MAX + 1];
asize = 2 * _POSIX2_LINE_MAX + 1;
text = xmalloc(asize);
size = 0;
while (cu_fgets(lbuf, sizeof(lbuf))) {
op = s = text + size;
p = lbuf;
EATSPACE();
for (; *p; p++) {
if (*p == '\\')
p++;
*s++ = *p;
}
size
Они использовали пробелы с помощью макроса EATSPACE
.
В FreeBSD sed
, который может неправильно обрабатывать \
как символы продолжения строки при использовании a
, i
, c
, поведение более странное. В моей FreeBSD 9.3:
$ echo 1 | sed -e 'i\ 1'
": extra characters after \ at the end of i command
но:
$ echo 1 | sed -e 'i\
2'
2
1
работает, и к тому же ест пробелы.
GNU sed
, семейная реликвия sed
не имеет этой проблемы.
Cuonglm дал лучший ответ , но для записи вот что делает GNU sed
:
echo foo | sed 'i\
This line starts with spaces.'
Вывод:
This line starts with spaces.
foo