복잡한 정규식 패턴을 개발하는 대신 파이프라인에서 find를 사용한 다음 grep -v를 사용하여 파일을 필터링하는 것이 훨씬 쉽다는 것을 알았습니다. 그러나 다음과 같이 zmv에 파이프를 연결하면:
find | grep -v TFLM | zmv "(*)" "TFLM \$1"
입력을 무시하고 계속해서 모든 파일에 변환을 적용합니다. 파이프 입력을 사용하도록 지시하는 방법이 있습니까? 필터링된 파일을 이동하고 zmv를 사용할 수 있을 것 같지만 실제로는 해결책이 아닙니다.
답변1
zmv
표준 입력에서 읽지 마십시오.
find
with here mv
또는 zmv
filename glob을 사용할 수 있지만 zsh
둘 다 사용할 수는 없으며 grep
전혀 다루지 않습니다. grep
파일 이름(삽입된 개행 문자를 포함할 수 있음)보다는 줄바꿈 텍스트를 사용해야 합니다.
파일 이름 glob 사용(현재 디렉터리에서만 작동하며 숨김이 아닌 파일에서만 작동):
zmv '^TFLM *' 'TFLM $f'
다음 과 같이 숨겨진 파일과 숨겨진 디렉터리의 파일을 포함하여 디렉터리 이름을 바꾸지 않고 반복적으로 find
:
zmv '(**/)(^TFLM *)(#qD^/)' '${1}TFLM $2'
사용하십시오 find
(그러나 충돌 처리가 없으므로 안전 옵션 zmv
을 추가하십시오 -i
):
find . ! -type d ! -name 'TFLM *' -exec sh -c '
for pathname do
mv -i "$pathname" "${pathname%/*}/TFLM ${pathname##*/}"
done' sh {} +
위치 bash
(숨겨진 파일은 제외하고 현재 디렉터리에만 적용):
shopt -s extglob
for name in !(TFLM *); do
mv -i -- "$name" "TFLM $name"
done
또는 bash
Perl rename
유틸리티를 사용하십시오.
shopt -s extglob
rename 's|/|/TFLM |' ./!(TFLM *)
(그렇지 않은 경우 ./
파일 이름이 로 시작하면 일부 변형이 실패합니다 -
. 모든 변형이 --
태그 옵션 end를 지원하는 것은 아닙니다).
답변2
그것은 당신이 일하는 방식이 아니라 find
당신 이 일하는 방식 grep
입니다 zmv
. 먼저 find
파일을 검색한 다음 grep
패턴을 검색하는 것은 의미가 없습니다. 이 명령에는 기본 에서 등 의 find
패턴 일치 기능이 내장되어 있습니다 . 원하는 경우 를 사용하여 정규식의 구문을 변경할 수도 있습니다 . 수행 중인 작업이 빠르지 않거나 명령이 너무 많을 뿐만 아니라 최악의 경우 명령에 오류가 발생하기 쉽다는 것입니다. 파일 내부의 공간.GNU find
-name
-iname
-path
-regex
-regextype
주의를 기울이는 한 이 솔루션은 다른 시스템 간에 이식성이 매우 find
뛰어 -exec
납니다 .mv
그러나 당신이 그것을 사용하고 있기 때문에 zsh
모든 영광을 사용해야하므로 -vn
옵션을 추가 zmv
하고 다른 모드를 시도하면 원할 가능성이 있습니다.
zmv -vn '(^(*TFLM*))' 'TFLM $1'
-v
장황하고 -n
실행을 차단하며 수행할 작업만 인쇄합니다(테스트에 유용합니다).
답변3
grep
나는 당신과 비슷하게 일하며 끝까지 명령을 계층화하는 것을 선호합니다 . 충동을 억제하는 것은 어렵지만 이 경우에는 그렇게 해야 합니다. 또는 목록에 대한 조치를 취하고 싶을 때 find | ...
끌어오기 시작해야 한다는 점을 정신적으로 기억해 두어야 합니다 xargs
. 이 지점에 도달하면 로 전환할 시간입니다 find <regex> -exec ...
.
귀하의 시나리오에서 여기 사용을 고려할 수 있는 패턴은 다음과 같습니다.
$ find . ! -name "*TFLM*" -exec zmv "{}" "TFLM {}" \;
그러나 @StephaneChazelas의 의견에 따르면 이것은 작동하지 않습니다.
zmv는 zsh 함수이므로 find를 통해 직접 실행할 수 없습니다. 누군가가 zmv 주위에 독립형 스크립트 래퍼를 만들었다고 해도 -exec zmv "{}"라고 부르는 것은 말이 되지 않으며(zmv의 목적을 완전히 무너뜨림) 명령 주입 취약점이 발생할 수 있습니다.
따라서 이 U&L Q&A에 표시된 방법 중 하나를 사용하는 보다 전통적인 옵션이 남았습니다.일괄 이름 바꾸기 파일.
또는 zmv
자체를 사용하여 직접 이름을 바꿉니다. 이제 그것을 사용하고 있으므로 도움을 요청할 필요조차 전혀 없을 zsh
것입니다 .zmv
find
$ zmv "(^*TFLM*)" "TFLM \$1"
노트:제 조언을 조금이라도 받아들이십시오 zmv
. zsh
저는 실제로 Zsh를 사용하지 않고 보통 하루 종일 Bash에 있습니다.