Нужно ли делать отступ в аргументе команды 'i\' в sed?

У вас должна быть возможность использовать -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 {} \;
3
27.09.2016, 05:08
2 ответа

Это расширение 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 не имеет этой проблемы.

3
27.01.2020, 21:13

Cuonglm дал лучший ответ , но для записи вот что делает GNU sed :

echo foo | sed 'i\
     This line starts with spaces.'

Вывод:

     This line starts with spaces.
foo
2
27.01.2020, 21:13

Теги

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