첫 글자로 1000 개가 넘는 글꼴을 구성하는 방법 (바람직하게는 터미널)을 찾고 있습니다.
기본적으로 디렉토리를 A-Z, #
만든 다음 파일 이름 첫 문자를 기준으로 글꼴 파일을 해당 디렉토리 로 이동하십시오. 숫자 [0-9]로 시작하거나 다른 특수 문자로 시작하는 글꼴은 #
디렉토리 로 이동됩니다 .
첫 글자로 1000 개가 넘는 글꼴을 구성하는 방법 (바람직하게는 터미널)을 찾고 있습니다.
기본적으로 디렉토리를 A-Z, #
만든 다음 파일 이름 첫 문자를 기준으로 글꼴 파일을 해당 디렉토리 로 이동하십시오. 숫자 [0-9]로 시작하거나 다른 특수 문자로 시작하는 글꼴은 #
디렉토리 로 이동됩니다 .
답변:
늦은 파이썬 옵션 :
#!/usr/bin/env python3
import os
import sys
import shutil
def path(dr, f): return os.path.join(dr, f)
dr = sys.argv[1]
for f in os.listdir(dr):
fsrc = path(dr, f)
if os.path.isfile(fsrc):
s = f[0]; target = path(dr, s.upper()) if s.isalpha() else path(dr, "#")
if not os.path.exists(target):
os.mkdir(target)
shutil.move(fsrc, path(target, f))
move_files.py
디렉토리를 인수로 사용하여 실행하십시오.
python3 /path/to/move_files.py /path/to/files
스크립트는 실제로 필요한 경우 (하위) 디렉토리 (-ies) (대문자) 만 작성합니다.
스크립트 :
파일을 나열하고 첫 번째 문자를 가져옵니다 (소스 경로 정의).
for f in os.listdir(dr):
s = f[0]; fsrc = path(dr, f)
항목이 파일인지 확인합니다.
if os.path.isfile(fsrc):
첫 번째 문자가 알파인지 아닌지에 대한 대상 폴더를 정의합니다.
target = path(dr, s.upper()) if s.isalpha() else path(dr, "#")
폴더가 이미 존재하는지 여부를 확인하고 그렇지 않은 경우 작성합니다.
if not os.path.exists(target):
os.mkdir(target)
항목을 해당 폴더로 이동합니다.
shutil.move(fsrc, path(target, f))
두 개의 명령과 두 개의 정규 표현식으로 코드를 읽을 수는 있지만 읽을 수 있습니다.
mkdir -p '#' {a..z}
prename -n 's|^[[:alpha:]]|\l$&/$&|; s|^[0-9]|#/$&|' [[:alnum:]]?*
이동할 파일이 너무 많고 프로세스 인수 목록에 맞지 않는 파일이 너무 많으면 (예, 제한이 있으며 몇 킬로바이트에 불과할 수 있음) 다른 명령을 사용하여 파일 목록을 생성 할 수 있습니다. prename
예 :
find -mindepth 1 -maxdepth 1 -name '[[:alnum:]]?*' -printf '%f\n' |
prename -n 's|^[[:alpha:]]|\l$&/$&|; s|^[0-9]|#/$&|'
이것은 리터럴 파일 이름을 이동시키지 않으려는 추가 이점이 있습니다 [[:alnum:]]?*
글로브 패턴과 일치하는 파일이없는 경우 . find
쉘 글 로빙보다 더 많은 일치 기준을 허용합니다. 대안은 nullglob
쉘 옵션 을 설정하고 의 표준 입력 스트림을 닫는 것입니다 prename
. 1
두 경우 모두 -n
스위치를 제거하여 실제로 파일을 이동하는 방법을 보여주는 것이 아니라 파일을 실제로 이동합니다.
추가: 하여 빈 디렉토리를 다시 제거 할 수 있습니다.
rmdir --ignore-fail-on-non-empty '#' {a..z}
1 shopt -s nullglob; prename ... <&-
zsh, 함수 및 몇 가지 zmv
명령을 신경 쓰지 않으면 :
mmv() {echo mkdir -p "${2%/*}/"; echo mv -- "$1" "$2";}
autoload -U zmv
zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'
이 mmv
기능은 디렉토리를 만들고 파일을 이동시킵니다. zmv
그런 다음 패턴 일치 및 대체를 제공합니다. 먼저 파일 이름을 알파벳으로 시작한 다음 다른 모든 항목을 이동하십시오.
$ zmv -P mmv '([a-zA-Z])(*.ttf)' '${(UC)1}/$1$2'
mkdir -p A/
mv -- abcd.ttf A/abcd.ttf
mkdir -p A/
mv -- ABCD.ttf A/ABCD.ttf
$ zmv -P mmv '([!a-zA-Z])(*.ttf)' '#/$1$2'
mkdir -p #/
mv -- 123.ttf #/123.ttf
mkdir -p #/
mv -- 七.ttf #/七.ttf
echo
in mmv
의 정의 없이 다시 실행 하여 실제로 이동을 수행하십시오.
나중에 디렉토리 이름을 대문자로 만들거나 대문자로 파일을 이동시키는 좋은 방법을 찾지 못했습니다 rename
.
mkdir {a..z} \#; for i in {a..z}; do for f in "$i"*; do if [[ -f "$f" ]]; then echo mv -v -- "$f" "$i"; fi; done; done; for g in [![:alpha:]]*; do if [[ -f "$g" ]]; then echo mv -v -- "$g" \#; fi; done
더 읽기 쉽게 :
mkdir {a..z} \#;
for i in {a..z}; do
for f in "$i"*; do
if [[ -f "$f" ]]; then
echo mv -v -- "$f" "$i";
fi
done
done
for g in [![:alpha:]]*; do
if [[ -f "$g" ]]; then
echo mv -v -- "$g" \#
fi
done
echo
실제로 파일을 이동시키는 테스트 후 제거
그리고
rename -n 'y/[a-z]/[A-Z]/' *
-n
테스트 후보기에 좋으면 제거 하고 다시 실행하십시오.
if [[ -d "${i^}" ]]
가변 i
자본을 mkdir {A..Z}
시작 하는 데 사용할 수 있습니다 .
글꼴을 포함하는 디렉토리 내의 다음 명령이 작동해야합니다. 글꼴 저장 디렉토리 외부에서 사용하려면 for f in ./*
로 변경 하십시오 for f in /directory/containing/fonts/*
. 이것은 매우 쉘 기반의 방법이므로 상당히 느리며 비재 귀적입니다. 일치하는 문자로 시작하는 파일이있는 경우에만 디렉토리가 작성됩니다.
target=/directory/to/store/alphabet/dirs
mkdir "$target"
for f in ./* ; do
if [[ -f "$f" ]]; then
i=${f##*/}
i=${i:0:1}
dir=${i^}
if [[ $dir != [A-Z] ]]; then
mkdir -p "${target}/#" && mv "$f" "${target}/#"
else
mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir"
fi
fi
done
폰트 저장 디렉토리 내에서 다시 하나의 라이너로 :
target=/directory/to/store/alphabet/dirs; mkdir "$target" && for f in ./* ; do if [[ -f "$f" ]]; then i=${f##*/}; i=${i:0:1} ; dir=${i^} ; if [[ $dir != [A-Z] ]]; then mkdir -p "${target}/#" && mv "$f" "${target}/#"; else mkdir -p "${target}/$dir" && mv "$f" "${target}/$dir" ; fi ; fi ; done
bash 매개 변수 확장을 사용하여 유사한 문자열 조작으로 find를 사용하는 방법은 재귀 적이며 순수 쉘 버전보다 약간 빠릅니다.
find . -type f -exec bash -c 'target=/directory/to/store/alphabet/dirs ; mkdir -p "$target"; f="{}" ; i="${f##*/}"; i="${i:0:1}"; i=${i^}; if [[ $i = [[:alpha:]] ]]; then mkdir -p "${target}/$i" && mv "$f" "${target}/$i"; else mkdir -p "${target}/#" && mv "$f" "${target}/#"; fi' \;
또는 더 읽기 쉽게 :
find . -type f -exec bash -c 'target=/directory/to/store/alphabet/dirs
mkdir -p "$target"
f="{}"
i="${f##*/}"
i="${i:0:1}"
i=${i^}
if [[ $i = [[:alpha:]] ]]; then
mkdir -p "${target}/$i" && mv "$f" "${target}/$i"
else
mkdir -p "${target}/#" && mv "$f" "${target}/#"
fi' \;
tr
, mkdir
및을 사용하여 각 파일 이름을 디렉토리 이름에 매핑하십시오 mv
.
find /src/dir -type f -print0 |
xargs -0 -I{} bash -c \
'dir=/dest/$(basename "{}" | cut -c1 | tr -C "a-zA-Z\n" "#" | tr "a-z "A-Z"); mkdir -p $dir; mv "{}" $dir'
tr
대문자로 변환하기 위해 다른 것을 추가했습니다 .
xargs
전화 하는 이유는 무엇 bash
입니까? find
while 루프에 출력을 파이프하고 read
레코드별로 기록 하는 것이 더 간단하고 읽기 쉬울까요?
while
루프 버전 ( bit.ly/2j2mhyb )이 더 좋습니다.
{}
하면 불쾌한 대체를 피할 수 있습니다 ( 예 :) . (마지막 마음 !)xargs
$1
xargs -0 -n1 -- bash -c 'dir=/dest/$(basename "$1" | ...); ...; mv "$1" "$dir"' _
_