확장자에 따라 파일을 정렬하고 올바른 폴더에 배치하는 스크립트를 만들었습니다. 예를 들어, abc.jpg
디렉토리에 배치됩니다 jpg
.
#!/bin/bash
#this script sorts files according to their extensions
oldIFS=$IFS
IFS=$'\n'
(find . -type f) > /tmp/temp
for var in `cat /tmp/temp`
do
name=`basename "$var"`
ext=`echo $name | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2-`
mkdir -p $ext
mv "$var" $ext/ 2> /dev/null
done
IFS=$oldIFS
이 스크립트의 문제점:
- IFS 사용에 관해서는 IFS 사용을 피하도록 노력해야 한다고 합니다.
- 파일 확장자가 없는 파일은 정렬되지 않습니다.
- bz라는 폴더에 abc.tar.bz와 같은 파일을 정렬하지만 이러한 파일은 tar.bz 폴더에 배치해야 합니다.
- 파일에 더 많은 숫자가 포함되어 있으면 내 스크립트의 9행을 참조하세요. 아무것도 아닌 것보다 (그 이름에) 포인트를 줍니다.
cut -d'.' -f2-
스크립트에서 파일 이름이 확장 부분에 포함됩니다.
예를 들어, 이름이 지정된 파일은i.am.live.in.india.and.i.study.computer.science.txt
이름이 지정된 폴더에 배치됩니다.study.computer.science.txt
또한 이 스크립트를 더 작고 깔끔하게 만들기 위해 조정을 제안할 수도 있습니다.
답변1
하위 디렉터리로 재귀
구문 분석된 출력을 find
신뢰할 수 없습니다. 파일 이름에 줄 바꿈이 있으면 어떻게 되나요? find … -exec …
안정적인 처리를 보장하는 데 사용됩니다 .
find . -type f -exec sh -c '…' {} \;
셸 조각은 을 …
받습니다 $0
. 이는 별도의 셸 프로세스이며 상위 스크립트에서 변수나 함수를 상속하지 않습니다. 동일한 셸 하위 프로세스를 사용하여 여러 파일을 처리하면 처리 속도를 높일 수 있습니다.
find . -type f -exec sh -c 'for x; do … done' _ {} +
이번에는 루프 내부에서 파일 이름이 변수에 있습니다 x
.
파일 이름 분해
외부 유틸리티(예: 등)를 호출하는 것은 sed
취약 cut
합니다. 특정 파일 이름이 손상되지 않도록 매우 주의해야 합니다. 이것은 필요하지 않습니다. 쉘의 내장 문자열 처리 기능만으로도 원하는 작업을 수행할 수 있습니다. 파일 이름이 주어지면 $x
:
directory=${x%/*}
basename=${x##*/}
extension=…
if [ -n "$extension" ]; then
mkdir -p "$directory/extension"
mv "$x" "$directory/extension"
fi
확장하다
파일 확장자는 무엇입니까? .
이름 중 하나 뒤에 오는 부분 입니다 . 어느 쪽인지에 대한 표준은 없습니다. 또는 같은 경우 에는 foo.tar.gz
확장자가 무엇인지 결정합니다 bar-1.2
.
foo-1.2.tar.gz
다음은 일반적인 압축 확장이 중첩된 것으로 간주하고 확장이 있는 것으로 간주되도록 확장에 문자를 포함하도록 요구하는 몇 가지 예제 코드입니다 tar.gz
.
extension=
while case "${basename##*.}" in
gz|bz2|xz) extension=.${basename##*.}$extension;; # stackable extension
*) false;;
do
basename=${basename%.*}
done
case "${basename##*.}" in
"$basename") :;; # no . ==> no extension
*[!0-9A-Za-z]*) :;; # only allow alphanumeric characters
*[A-Za-z]*) extension=${basename##*.}$extension;; # non-stackable extension
*) false;; # require at least one letter
esac
extension=${extension#.}
답변2
확장 기능의 일반적인 문제를 식별하는 것은 어렵지만 스크립트를 약간 정리할 수 있습니다.
find
확장자가 있는 파일만 고려하도록 지시 합니다.-iname '*.*'
awk
직접 시도하는 대신 다음을 사용하십시오cut
.- 스크립트를 사용한 다음
find
실행하도록 지시하십시오.
따라서 다음과 같은 스크립트가 필요합니다 move.sh
.
#! /bin/bash
for i
do
ext=/some/where/else/$(awk -F. '{print $NF}' <<<"$i")
mkdir -p "$ext"
mv "$i" "$ext"
done
그런 다음 다음을 실행하십시오 find
.
find . -name '*.*' -type f -exec move.sh {} +
폴더 내에서 재정렬할 수 없다는 문제가 있으므로 다음을 사용할 수 있습니다 xargs
.
find . -name '*.*' -type f -print0 > /tmp/temp
xargs -0 move.sh < /tmp/tmp
관련된 효율성에 대해서는 잘 모르겠지만 다른 접근 방식은 모든 확장자를 가져온 다음 관련된 모든 파일을 한 번에 이동하는 것입니다.
그것은 다음과 같습니다:
find . -name '*.*' -type f -print0 | sed -z 's/.*\.//g' | sort -zu > /tmp/file-exts
그러면 고유한 파일 확장자 목록이 제공됩니다. 그러면 우리는 move.sh
다음과 같이 보일 것입니다 :
#!/bin/bash
for i
do
mkdir -p "$i"
find . -name "*.$i" -type f -exec mv -t "$i" {} +
done
우리는 그것을 실행할 것입니다:
xargs -0 move.sh < /tmp/file-exts
sed
나는 이 게시물에서 예 를 들어 sort
지원 ( -z
NUL 종료 라인으로 작업 find
하고 xargs
성공할 수 있도록 허용) 과 같은 많은 가정을 했습니다 .