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

Мне нужно переименовать пару файлов, используя сценарий оболочки, с помощью определенного «ключа». Этот ключ включает в себя как строки, так и извлеченные части пути к файлу, которые я получаю с помощью 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 в настоящее время.

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 
  • Создайте список файлов из файла, содержащего ряд шаблонов глобусов
  • Как расширить подстроку команды?
  • Tmux-logging: zle reset-prompt причина войти в файл журнала
  • Перенаправить вывод на полпути через скрипт и восстановить позже
  • Команда scp, работающая в bash, не работает в zsh
  • Неограниченная история в zsh
  • Проблемы с Vim при использовании ZSH
  • Стандартное завершение Zsh отлично работает, так почему люди рекомендуют загружать модуль compinit?
  • Как повторить виджет zle произвольное количество раз, когда открыто меню завершения?
  • Исполняемые файлы показывают с символом * рядом с их именем в выводе ls
  • bash эквивалент zsh $ @
  • Linux и Unix - лучшая ОС в мире.