쉘에서 상위 디렉토리의 "basename"만 추출하려면 어떻게 해야 합니까?

쉘에서 상위 디렉토리의 "basename"만 추출하려면 어떻게 해야 합니까?

쉘 스크립트를 사용하여 특정 "키"로 여러 파일의 이름을 바꿔야 합니다. 키는 문자열과 .txt 파일을 사용하여 얻은 파일 경로의 추출된 부분으로 구성됩니다 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/

이름을 바꿔야 해요../색인/폴더../c2_[상위 폴더 이름]/. 이것이 내가 시도하는 것입니다:

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를 사용하고 있다는 점을 무시하십시오.

답변1

zsh사용하는 것이 가장 좋습니다zmv:

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

(행복하면 삭제 -n).

휴대용(POSIXsh) 해결책:

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

( -i가난한 사람의 정신 상태 점검을 대신하여 zmv).

사용하고 싶다면find-mindepth이식 가능(POSIXly)에서는 / 를 잊어야 하며 , 다음의 조합 -maxdepth으로 대체할 수 있습니다 .-path-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숨겨진 디렉터리도 검색한다는 것입니다.

여기 또는 사이트의 수많은 Q&A에 설명된 표준 매개변수 확장 연산자를 사용합니다 ${var#pattern}.${var%pattern}POSIX 쉘 사양.

답변2

그만한 가치가 있는 만큼 시도해 보세요.

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

Stéphane이 언급한 것처럼 그 다음의 첫 번째 매개변수는 sh -c "..."스크립트 이름으로 처리되며 위에서 제공되며 $0일반적인 위치 매개변수와 다릅니다 $1. 후자에는 shift및 와 같이 이를 처리하도록 특별히 설계된 도구가 있지만 $@처리할 수는 없습니다 $0.

단 하나의 인수에 대해서는 using이 $0작동하지만 쉘 이름이 다른 목적으로 사용될 수 있으므로 sh거기에서 합리적인 것을 설정한 다음(예를 들어) 실제 인수를 그 뒤에 두는 것이 좋습니다.

답변3

일한 적이 없다ZTE, 하지만 아래 코드는 정상적으로 실행됩니다.세게 때리다

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

관련 정보