아직 문자열이나 문자열 집합이 포함되어 있지 않은 파일의 이름을 바꾼 다음 해당 문자열을 포함하는 명령줄 도구가 있습니까?
따라서 특정 폴더에 있는 모든 파일은 "높은 우선순위" 이름을 가져야 high
하지만 일부는 있고 일부는 그렇지 않습니다. 모든 파일에 추가하는 것이 아니라 high
파일명에 포함되어 있는지 먼저 확인하고 포함되어 있지 않으면 이름 앞에 추가하는 방법은 무엇인가요 ?
답변1
GNU 병렬이 있는 경우:
parallel mv {} '{= /high/ or $_="high$_" =}' ::: *
답변2
그리고 zsh
:
autoload zmv # best in ~/.zshrc
zmv '^*high*' 'high-$f'
대소문자를 구분하지 않는 일치:
zmv '^*(#i)high*' 'high-$f'
답변3
bash
이 패턴은 다음을 사용 하는 경우 !(*high*)
문자열을 포함하지 않는 현재 디렉터리의 모든 이름과 일치합니다 .high
extglob
$ shopt -s extglob
$ ls
1 2 3 4-high
$ ls -d -- !(*high*)
1 2 3
그런 다음 이 패턴과 일치하는 이름을 반복하여 일치하는 각 이름을 바꿀 수 있습니다.
shopt -s extglob nullglob
for name in !(*high*); do
[[ ! -f $name ]] && continue
mv -- "$name" "high-$name"
done
여기서 일어나는 일은 루프 앞에 extglob
및 를 설정한 것입니다 nullglob
(패턴이 일치하지 않는 경우 와일드카드 패턴을 그대로 두는 대신 와일드카드 패턴을 사라지게 만듭니다). dotglob
숨겨진 이름의 이름도 바꾸고 싶다면 해당 이름도 활성화할 수 있습니다.
그런 다음 루프는 일반 파일을 참조하지 않는 모든 이름(예: 디렉터리 이름) high-
을 건너뛰고 이름 앞에 mv
.
--
mv
대시로 시작하는 파일 이름을 옵션 집합으로 잘못 해석하는 것을 방지하기 위해 명령에 추가합니다 .
테스트 파일 세트에서 실행:
$ ls
1 2 3 4-high
위 코드를 셸에 직접 붙여넣으면 됩니다.
$ shopt -s extglob nullglob
$
$ for name in !(*high*); do
> [[ ! -f $name ]] && continue
>
> mv -- "$name" "high-$name"
> done
$ ls
4-high high-1 high-2 high-3
rename
다음과 같이 Perl 유틸리티를 사용할 수도 있습니다.
shopt -s extglob
rename -v 'if (-f) { s/^/high-/ }' -- !(*high*)
이것은 -f
이 답변의 첫 번째 변형에서 루프 테스트를 Perl로 이동하지만 여전히 동일한 파일 이름 글로빙 패턴을 사용하여 이름을 바꿀 파일을 선택합니다. 이렇게 -f
하면 이름 바꾸기가 일반 파일에만 영향을 미칩니다(디렉토리 등은 제외).
셸에 의존하지 않는 확장된 와일드카드 패턴의 변형은 다음과 같습니다.
rename -v 'if (-f && !/high/) { s/^/high-/ }' -- *
이는 호출 시 이름 high
에 이미 문자열이 포함되어 있는지 테스트 rename
하고 그런 경우 파일 이름 바꾸기를 건너뜁니다. glob은 *
현재 디렉터리의 모든 파일을 선택합니다(숨겨진 파일 제외).