특정 문자 수를 포함하는 모든 파일 이름을 가져옵니다.

특정 문자 수를 포함하는 모든 파일 이름을 가져옵니다.

정확한 길이가 16자(숫자 및 소문자)인 모든 파일 이름을 변경하고 싶습니다. 다음 코드 조각에서 자리 표시자를 사용하려고 [0-9a-z]{16}시도 했지만 작동하지 않습니다.[0-9a-z]\{16\}regX

for file in <regX>
do
  mv "$file" "${file}.txt"
done

답변1

쉘 글로빙 패턴정규 표현식이 아닙니다. 비슷해 보일 수도 있지만 어떤 면에서는 상당히 다르게 작동합니다.

정규식은 [0-9a-z]{16}언급된 문자 범위의 16개 문자를 포함하는 문자열과 일치합니다(일치를 포함하는 문자열은 더 길 수 있음).

동등한 쉘 글로빙 패턴은 다음과 같습니다.

*[0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z]*

이 때문입니다

  1. Globbing 패턴은 "이전 N번 반복"이라는 수정자를 지원하지 않습니다.
  2. Globbing 패턴은 기본적으로 시작과 끝에 고정됩니다. 그래서 *패턴의 시작과 끝 부분에 삽입을 했습니다. A는 *임의 개수의 모든 문자와 일치합니다. 일치시키려면 이 항목을 제거하세요.정확히16자.

Perl을 사용하여 16개의 문자열을 만들 수 있습니다 [0-9a-z]:

$ pattern="$( perl -e 'print "[0-9a-z]" x 16' )"

를 사용하면 bash현재 디렉터리의 모든 이름을 반복한 다음 이름이 정규식과 일치하는지 테스트할 수 있습니다.

for name in *; do
    if [[ -f "$name" ]] && [[ "$name" =~ ^[0-9a-z]{16}$ ]]; then
        echo mv "$name" "$name.txt"
    fi
done

echo올바른 일을 하고 있다는 것을 알게 되면 을 제거하십시오 .

더 긴 이름이 일치하지 않도록 패턴을 고정했습니다. 또한 -f테스트를 통해 우리가 얻는 이름이 실제로 일반 파일의 이름인지 확인하고 있습니다 .

답변2

와 함께익스트글로브

shopt -s extglob
for file in +([0-9a-z])
do
    [[ ${#file} == 16 ]] && echo mv "$file" "${file}.txt"
done
  • +([0-9a-z])하나 이상의 [0-9a-z]문자를 의미합니다.
  • ${#file}파일 이름의 길이를 제공합니다
  • echo시험 실행을 위한 것이므로 문제가 해결되면 제거하세요.

답변3

renamePerl-rename( Debian 기반 시스템 또는 기타 시스템에서 호출됨)이 있는 경우 다음을 perl-rename수행할 수 있습니다.

perl-rename -n 's/^[0-9a-z]{16}$/$&.txt/' *

원하는 대로 되었다면 -n파일 이름을 실제로 바꾸려면 을 제거하십시오. 구문은 perl-renameperl 명령입니다. 여기서는 대체 연산자( )를 사용하여 로 s/from/to/대체합니다 . 이 경우 정규식은 " 일치하는 항목"을 의미하는 특수 변수와 확장자 입니다 .fromtofromto$&.txt


Shell glob을 사용하여 이 작업을 수행하려면(사용@쿠살라난다의또는@선딥의접근 방식은 단지 완료를 위한 것입니다):

for f in [0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z]; do
    mv -- "$f" "$f".txt
done

GNU를 사용하면 find:

find . -regextype posix-extended -regex '.*/[0-9a-z]{16}' -exec mv {} {}".txt" \;

답변4

L16=$(csh -c 'repeat 16 echo -n "?"')
find . -name "$L16" ! -name '*[!0-9a-z]*' -exec sh -c '
   mv "$1" "$1.txt"
' {} {} \;

관련 정보