실수로 셸에 붙여넣고 이름이 모두 난수인 빈 파일 묶음을 만들었습니다. 이 모든 것을 한 번에 제거하는 효과적인 방법은 무엇입니까?
디렉토리에 필요한 다른 파일이 있습니다. 그 파일에는 숫자가 있지만 숫자로 시작하는 파일은 모두 잘못된 것입니다. 정규식 제거를 좋아하시나요?
답변1
삭제하려는 파일이 비어 있다는 말씀입니다. 이러한 파일을 삭제하는 한 가지 방법은 빈 파일만 삭제하는 것입니다. 이렇게 하면 콘텐츠가 포함된 파일이 삭제되지 않습니다. 나는 이것이 이름으로 분류하는 것보다 더 안전하다고 믿습니다. 현재 디렉토리에서 빈 파일을 삭제하는 명령은 다음과 같습니다.
find ./ -size 0 -delete
Stéphane Chazelas는 건설적인 의견을 제공했습니다. 더 나은 명령은 다음과 같습니다.
find ./ -maxdepth 1 -type f -size 0 -delete
답변2
그리고 zsh
:
rm -f -- *(.L0)
삭제됩니다정기적인( .
) 숨겨지지 않은 빈 파일( L
길이 0).
내부 bash
쉘 또는 기타 쉘:
zsh -c 'rm -f -- *(.L0)'
이름이 ASCII 십진수로만 구성된 파일 1을 삭제하려면:
rm -f <->
여기서는 특정 범위 내의 숫자 <->
와 일치 하지만 경계는 없습니다. <x-y>
마찬가지로 다른 쉘에도 zsh -c '...'
.
에서는 bash
다음 작업도 수행할 수 있습니다.
(shopt -s extglob failglob; rm -f +([0123456789])
또는 ksh93
:
rm -f ~(N)+([0123456789])
두 가지를 결합할 수 있습니다(모든 숫자가 포함된 빈 일반 파일 제거).
rm -f <->(.L0)
POSIX 셸 및 유틸리티의 경우 이에 상응하는 내용은 다음과 같습니다.
LC_ALL=C find . ! -name . -prune -type f -size 0c \
! -name '*[!0-9]*' -exec rm -f {} +
모든 숫자로 구성된 파일을 찾으려면 숫자가 아닌 파일이 하나 이상 포함된 파일을 제외한 모든 파일을 찾습니다. -size 0c
크기의 파일과 일치바이트²는 0입니다.
LC_ALL=C
범위에 0123456789만 포함되어 있는지 확인하고 0-9
, 더 중요한 것은 파일 이름이 로캘과 다른 문자 집합으로 인코딩된 경우 명령이 작동한다는 것입니다. 예를 들어, 이것이 없으면 GNU 및 UTF-8 로케일에서 ( latin1로 인코딩된) find
파일은 숫자가 아닌 문자가 발견되지 않아서가 아니라(숫자가 아닌 문자로만 구성됨) 삭제됩니다. 문자로 디코딩할 수 없는 0xe9 바이트 (0개 이상의 문자와 일치)는 일치하지 않습니다.$'St\xe9phane'
Stéphane
*
zsh
glob은 문자의 일부를 형성하지 않는 바이트가 특수 문자의 일부 형태로 처리되기 때문에 문제가 없습니다. 반면 bash glob 및 현재 버전에서는 bash
입력 문자열을 문자로 디코딩할 수 없는 경우 바이트 단위로 전환됩니다. 일치(C 언어 환경에서처럼 동작하도록 만들기).
¹ 이번에는 이에 국한되지 않습니다.정기적인파일(심볼릭 링크 포함), fifos... 파일 유형목차rm
하지만 해당 옵션을 전달하지 않으면 디렉터리가 삭제되지 않으므로 삭제되지 않습니다 -r
.
-size 0
² 크기가 반올림되므로 여기서도 작동하는 (크기는 512바이트에서 0)을 사용할 수도 있습니다 .위로따라서 현재로서는 바이트 크기의 파일이 512바이트 단위로 구성된 것으로 간주되지만 보다 일반적으로는 정확한 크기 일치를 위해 해당 접미사를 -size 0
사용하는 것이 좋습니다. 예를 들어 512 파일 크기의 파일에는 적용되지 않습니다. 크기는 1부터 512까지입니다. 크기가 정확히 512인 파일 의 경우 . glob 한정자 의 경우 기본 단위는 다음과 같습니다.c
-size 1
-size 512c
zsh
L
바이트, 512바이트 단위가 아닙니다.
답변3
글로브를 사용할 수 있습니다. 예를 들어
echo rm [0-9]*
echo
보관하고 싶은 항목이 삭제되지 않는다고 확신하면 삭제하세요. 그런데 rm
별칭 (우발적인 파일 삭제에 대한 매우 일반적인 보호 기능)이 있는 경우 이를 덮어쓰는 대신 rm -i
실행해야 합니다. 그렇지 않으면 각 파일에 대해 입력해야 합니다.command rm [0-9]*
rm [0-9]*
y
또는 mv
파일을 새로 생성된 디렉터리에 배치하고 유지하려는 파일을 개별적으로 원래 위치로 이동한 다음 디렉터리를 삭제합니다. 예를 들어
mkdir /tmp/junk
mv [0-9]* /tmp/junk
cd /tmp/junk
# investigate and mv any you want to keep
cd -
rm -rf /tmp/junk
다른 대안:
단일 bash 명령줄에서 수용할 수 있는 것보다 더 많은 파일을 삭제하려면 다음을 수행하세요.
for i in {0..9}; do rm "$i"*; done
또는
find . -maxdepth 1 -type f -empty -name '[0-9]*' -delete
또는 평가판:
find . -maxdepth 1 -type f -empty -name '[0-9]*' -print | less
이 -maxdepth 1
옵션은 find가 하위 디렉토리로 반복되는 것을 방지하고 -type f
일반 파일(디렉토리, 소켓, 명명된 파이프 등이 아님)만 일치하도록 제한하고 -empty
빈 파일만 일치하는지 확인합니다.
또는 find
및 mv
:
mkdir /tmp/junk
find . -maxdepth 1 -type f -empty -name '[0-9]*' -exec mv -t /tmp/junk/ {} +
(GNU에는 이동할 파일 목록 앞에 대상 디렉터리를 지정하는 옵션이 mv
있어야 합니다 . GNU mv는 Linux에서 표준입니다.)-t
답변4
숫자로 시작하는 모든 파일을 삭제하려면 bash for
루프를 사용하는 한 가지 방법이 있습니다.
for n in [0-9]* ; do rm -i "${n}" ; done
쉘 glob [0-9]*(숫자 뒤에 하나 이상의 임의 문자가 오는 것을 의미)와 일치하는 모든 파일을 반복합니다. 각 파일( 안전을 위해 잠정적으로 $n
" "라고 함)에 대해 해당 파일을 삭제합니다. 전체 파일 로드를 자동으로 삭제하는 것이 조금 조심스럽기 때문에 대화형으로 -i를 추가했지만. ${n}
귀하는 귀하의 재량에 따라 이 콘텐츠를 삭제할 수 있습니다.
더욱 안전하려면 삭제하기 전에 각 파일이 비어 있는지 확인할 수 있습니다.
for n in [0-9]* ; do if [[ `ls -l "${n}" |sed 's/[^ ]* [^ ]* [^ ]* [^ ]* \([0-9]*\) .*/\1/'` -eq 0 ]] ; then rm "${n}" ; fi ; done
이제 각 파일에 대해 sed
교체를 통해 긴 목록을 전달하여 줄을 다섯 번째 필드(파일 크기)로 바꾸고 0과 같은지 테스트합니다. 그렇다면 각 파일 뒤에 "예"라고 대답하지 않고도 안전하게 삭제할 수 있습니다.
이것은 나에게 효과적이었지만 보관하려는 다른 파일로 둘러싸인 많은 수의 파일을 삭제하는 경우 -i
올바른 파일이 선택되는지 확인하는 것부터 시작하는 것이 좋습니다. 그러다가 Ctrl-C
편 해지면 -i
.
또는 디렉터리를 백업하고 복사본에 대해 명령을 실행한 후 diff -r
백업을 삭제하기 전에 문제가 없는지 확인하세요.