Копировать файл в несколько (переменных )папок

Это ожидаемое поведение.

Флаг -i/ --in-placeредактирует временную копию файла, а затем перемещает эту копию поверх оригинала.

Итак, когда вы:

sed -i 'bla' symlink

Что делает sed:

sed 'bla' symlink > temp_file
mv temp_file symlink

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

Информация взята из комментария в . Как предотвратить уничтожение символических ссылок sed -i?

0
19.12.2020, 13:51
2 ответа

С помощью zshвы также можете использовать его zmvфункцию автозагрузки:

autoload -Uz zmv # best in ~/.zshrc
zmv -C '(**/)(foo.txt)(#q.)' '${1}bar.txt'

или:

zmv -C '**/foo.txt(#q.)' '$f:h/bar.txt'

Преимущество использования zmvпо сравнению с написанием цикла вручную состоит в том, что он имеет несколько проверок безопасности, которые предотвращают необратимые ошибки.

2
18.03.2021, 22:41

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

find rootdir -type f -name foo.txt -execdir cp {} bar.txt \;

Это ищет обычные файлы с именем foo.txtв любом месте или под rootdir, и когда он найден, cpиспользуется для его копирования с именем bar.txtв том же каталоге. Опция -execdirне является стандартной -, но обычно реализуется и запускает данную утилиту в каталоге, где был найден файл. {}будет заменено именем найденного файла.

Как вариант,

find rootdir -type f -name foo.txt -exec sh -c '
    for pathname do
        cp "$pathname" "${pathname%/*}/bar.txt"
    done' sh {} +

Это делает в основном то же самое, но вызывает короткий скрипт в -строке sh -cс пакетами найденных foo.txtфайлов. cpв цикле скопирует каждый из них в тот же каталог, что и найденный файл, но с заменой имени файла на bar.txt.

Используя **, как вы упомянули в вопросе (, предполагая оболочку bash):

shopt -s globstar nullglob dotglob

for pathname in rootdir/**/foo.txt; do
    cp "$pathname" "${pathname%/*}/bar.txt"
done

В bashустановка параметра оболочки globstarпозволяет использовать **для рекурсивного сопоставления с подкаталогами, а dotglobпозволяет шаблонам также сопоставлять скрытые имена. Параметр оболочки nullglobприводит к полному исчезновению шаблонов, а не их раскрытию в случае отсутствия соответствия.

Опять же, но сzsh(явным запросом обычных файлов и включением эквивалентной обработки подстановки, как dotglobи nullglobдляbash):

for pathname in rootdir/**/foo.txt(.ND); do
    cp $pathname $pathname:h/bar.txt
done

Здесь $pathname:hбудет таким же, как $pathname, но с удаленной частью имени файла из пути(:hкак в «только голове», а не в конце бита ).

3
18.03.2021, 22:41

Теги

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