Как извлечь только «базовое имя» родительского каталога в оболочке?

Мне нужно переименовать пару файлов, используя сценарий оболочки, с помощью определенного «ключа». Этот ключ включает в себя как строки, так и извлеченные части пути к файлу, которые я получаю с помощью find .

Я нахожусь на Mac, OSX El Capitan и пользуюсь ZSH. Вот дерево каталогов :

 ├── 300x250 │  ├── 300x250-img-fallback.jpg │  └── index/ ├── 300x600 │  ├── 300x600-img-fallback.jpg │  └── index/ ├── 336x280 │  ├── 336x280-img-fallback.jpg │  └── index/ └── 970x250 ├── 970x250-img-fallback.jpg └── index/ 

Мне нужно переименовать ../index/ папки в ./c2_[parentFolderName]/ . Это то, что я пытаюсь:

 find . -type d -mindepth 2 -maxdepth 2 -exec sh -c 'echo -- mv "$0" "$(dirname "$0")"/"C2_"$(basename "$0/..")""' {} \; 

Кажется, это не лучший способ получить basename имя родителя.

 find . -name "*index" -exec sh -c 'echo -- mv "$0" "$(dirname "$0")"/"C2_"$(basename "$0/..")""' {} \; 

Это один из вариантов, который также не работает (нет причин, почему это должно :)).

Я довольно новичок в сценариях оболочки и стараюсь как можно больше учиться в агностическом режиме оболочки , поэтому, пожалуйста, не обращайте внимания на то, что я использую ZSH в настоящее время.

  • Как изменить ключ для автозаполнения в ZSH?
  • zpool указывает, что зоны находятся в режиме SUSPENDED
  • zsh не может содержать некорректные `$ *` и `$ @` равные
  • Передача команды с аргументами скрипту
  • Zsh: dirs в обратном порядке
  • Все файлы в каталоге, которые не заканчиваются в определенной строке?
  • Функция zsh: достигается максимальный уровень вложенных функций
  • Переменные среды установки OS X
  • 3 Solutions collect form web for “Как извлечь только «базовое имя» родительского каталога в оболочке?”

    Лучше всего было бы использовать zsh zmv :

     autoload zmv # best in ~/.zshrc zmv -n '(*)/index' '$1/C2_$1' 

    (удалите -n когда -n счастливы).

    Для портативного ( POSIX sh ) решения:

     for dir in */index; do mv -i -- "$dir" "${dir%/*}/C2_${dir%/*}" done 

    (использование -i как zmv бедного человека для проверки здравомыслия zmv делает).

    Если вы хотите использовать find portably (POSIXly), вам нужно забыть о -mindepth / -maxdepth , который вы можете заменить комбинациями -prune и -prune :

     LC_ALL=C find . -path './*/*' -prune -name index -exec sh -c ' for dir do top=${dir#./} top=${top%/*} mv -i -- "$dir" "$top/C2_$top" done' sh {} + 

    Одно отличие от двух других подходов состоит в том, что он не будет следовать символическим ссылкам и что он также будет искать index в скрытых каталогах.

    Они используют стандартные операторы расширения параметров ${var#pattern} , ${var%pattern} описанные в бесчисленных Q & As здесь или в спецификации оболочки POSIX .

    Для чего это стоит, ваша попытка

     find . -type d -exec sh -c 'echo -- mv "$0" "$(dirname "$0")"/"C2_"$(basename "$0/..")""' {} \; 

    похоже, почти работает, за исключением того, что basename не интерпретирует точку-точку. Но взятие dirname должно дать вам имя родителя, и вы можете взять basename этого. Что-то вроде этого:

     $ mkdir -p 300x250/index 970x250/index $ find . -name index -exec sh -c 'echo mv "$1" "$(dirname "$1")/C2_$(basename "$(dirname "$1")")"' sh {} \; mv ./300x250/index ./300x250/C2_300x250 mv ./970x250/index ./970x250/C2_970x250 

    Как упоминал Стефан, первый аргумент после sh -c "..." берется как имя скрипта, которое идет в $0 и отличается от обычных позиционных параметров от $1 вверх. У последних есть инструменты, специально предназначенные для работы с ними, такие как shift и $@ , и они не работают с $0 .

    Только для одного аргумента использование $0 может работать, но поскольку имя оболочки можно использовать для других целей, предпочтительнее установить что-то разумное (например, sh ) и поместить фактические аргументы после этого.

    Никогда не работал над ZSH , но ниже код работает очень хорошо на bash

     SHW@SHW:/tmp/test1 # tree . ├── 300x250 │  ├── 300x250-img-fallback.jpg │  └── index ├── 300x600 │  ├── 300x600-img-fallback.jpg │  └── index ├── 336x280 │  ├── 336x280-img-fallback.jpg │  └── index └── 970x250 ├── 970x250-img-fallback.jpg └── index 8 directories, 4 files SHW@SHW:/tmp/test1 # for i in `find . -type d -name index`; do mv $i `dirname $i | cut -c3-`/c2_`dirname $i | cut -c3-`; done SHW@SHW:/tmp/test1 # tree . ├── 300x250 │  ├── 300x250-img-fallback.jpg │  └── c2_300x250 ├── 300x600 │  ├── 300x600-img-fallback.jpg │  └── c2_300x600 ├── 336x280 │  ├── 336x280-img-fallback.jpg │  └── c2_336x280 └── 970x250 ├── 970x250-img-fallback.jpg └── c2_970x250 8 directories, 4 files 
    Linux и Unix - лучшая ОС в мире.