Как переименовать шаблон в одном файле другому по нескольким каталогам рекурсивно

Таким образом, вот то, что я думаю, что Вы испытываете: Все работает, кроме настольных частей. В основном, никакие панели, никакие значки на рабочем столе, и т.д.

Я не совсем уверен, как зафиксировать панели, так как это зависело бы от Вашей настольной среды, но для значков на рабочем столе, это - вероятно, Наутилус, являющийся жадиной.

Только запустите Наутилус (nautilus & в работах терминала), и необходимо видеть, что значки на рабочем столе раскрываются назад.

1
25.05.2013, 02:34
3 ответа

Это должно работать:

find . -type f -name "*.GEOT14246.*" -print0 | \
xargs -0 rename 's/GEOT14246/GEOT15000/'

данный нет названных каталогов *.GEOT14246.*


Находка использования варианта удара могла быть чем-то как:

while IFS= read -r -d $'\0' file; do
    printf "MV: %-40s => %s\n" "$file" "${file/GEOT14246/GEOT15000}"
    mv "$file" "${file/GEOT14246/GEOT15000}"
done < <(find . -type f -name "*.GEOT14246.*" -print0)
              |                                 |
              +--- this is starting directory   +--- This ensures no hiccup
                                                     if newline etc. in name

Родственник, но полный, пути передаются от находки – который необходимо видеть от printf оператор.

Новое имя компилируется при помощи удара:

${some_variable/find/replace}

заменять все findиспользование:

${some_variable//find/replace}

и т.д. Больше здесь. Это могло также быть хорошим чтением: BashPitfalls, UsingFind.

Прочитайте некоторые руководства как BashGuide. Найдите некоторые учебные руководства онлайн, но обычно никогда не доверяйте им, спросите здесь или относительно irc.freenode.net #bash.


Вы не должны вызывать сценарий путем вызова sh. Это также назвало бы Оболочку Bourne (sh), и не Граница Снова окружают (колотят). Если Вы намереваетесь выполнить его с ударом; проблема bash file. .sh расширение также неуместно.

То, что Вы обычно делаете, делают исполняемый файл файла:

chmod +x script_file

и затем выполненный это с:

./script_file

Хижина заботится, какой среды сценарий должен работать в.


В Вашем сценарии Вы не используете переданный путь нигде. Сценарий имеет "список аргументов", начинающий с $0 который является названием сценария, $1 первый аргумент, $2 во-вторых, - и так далее.

В Вашем сценарии Вы сделали бы что-то в направлении:

# Check if argument 1 is a directory, if not exit with error
if ! [[ -d "$1" ]]; then
    printf "Usage: %s [PATH]\n" "$(basename "$0")" >&2
    exit 1
fi

# OK
path="$1"

while ...

done < <(find "$path" -type f ...)

Ваш ток mv оператор переместил бы все файлы в то, везде, где Вы даете команду – в один файл, названный.GEOT14246. (как в перезаписи для каждого mv оператор):

Перед запущенным скриптом:

$ tree
.
└── d1
   ├── a1
   │  ├── a2
   │  │  ├── a3
   │  │  │  └── foo.GEOT14246.faa
   │  │  └── foo.GEOT14246.faa
   │  └── foo.GEOT14246.faa
   └── b1
     ├── b2
     │  ├── b3
     │  │  └── foo.GEOT14246.faa
     │  └── foo.GEOT14246.faa
     └── foo.GEOT14246.faa

После запущенного скрипта:

$ tree
.
├── d1
│  ├── a1
│  │  └── a2
│  │  └── a3
│  └── b1
│    └── b2
│    └── b3
└── *.GEOT15000.*

Также файлы / пути с пробелами или другими забавными вещами заставили бы сценарий разложиться и распространить опустошение. Для этого необходимо заключить переменные в кавычки (такой как "$file").

3
27.01.2020, 23:15

В ударе 4.0 или позже Вы могли также использовать globstar:

shopt -s globstar
for f in **/*GEOT14246*; do mv "$f" "$f{/14246/15000}"; done
rename s/14246/15000/ **/*GEOT14246*
  • Шаблон шарика также соответствует папкам, которые содержат GEOT14246
  • Обе опции относятся к целому пути
  • Может быть список аргументов слишком длинная ошибка, если шаблон шарика расширен, чтобы быть длиннее, чем getconf ARG_MAX

Или использование находит и читало:

find . -name '*GEOT14246*' | while read f; do mv "$f" "${f/14246/15000}"; done
  • -print0 не нужно, если пути не содержат переводы строки
  • IFS= не нужно, если пути не запускаются или заканчиваются символами в IFS
  • -r не нужно, если пути не содержат обратные косые черты
  • < <() не нужно, если Вы не изменяете переменные вне цикла с условием продолжения или чего-то
2
27.01.2020, 23:15

В ударе нет простой остроты, но существует один в zsh. Добавьте строку autoload -U zmv к Вашему ~/.zshrc. Затем можно использовать zmv и подстановочные знаки zsh и замена параметра.

zmv '/path/to/starting/dir/**/*GEOT14246*' '${f//GEOT14246/GEOT15000}'

Обратите внимание, что это заменяет GEOT14246 в именах файлов также. Вам нужны кавычки вокруг обоих аргументов потому что zmv анализирует их снова.

На Linux, с ударом или zsh, можно использовать rename вместо этого. Это заменяет только первое вхождение GEOT14246 в каждом пути.

rename GEOT14246 GEOT15000 /path/to/starting/dir/**/*GEOT14246*

В ударе необходимо включить ** рекурсивный шарик сначала с shopt -s globstar (добавьте эту строку к Вашему ~/.bashrc).

Если Вашим дистрибутивом Linux является Debian, Ubuntu или производная, rename команда является другой. Используйте любой из них:

rename.ul GEOT14246 GEOT15000 /path/to/starting/dir/**/*GEOT14246*
rename 's/GEOT14246/GEOT15000/g' /path/to/starting/dir/**/*GEOT14246*
1
27.01.2020, 23:15

Теги

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