rm, cp, mv 명령의 인수 목록이 너무 깁니다.


629

UNIX의 디렉토리에 수백 개의 PDF가 있습니다. PDF 이름은 실제로 길다 (약 60 자).

다음 명령을 사용하여 모든 PDF를 함께 삭제하려고 할 때 :

rm -f *.pdf

다음과 같은 오류가 발생합니다.

/bin/rm: cannot execute [Argument list too long]

이 오류에 대한 해결책은 무엇입니까? 이 오류가 mvcp명령에도 발생합니까 ? 그렇다면 이러한 명령을 해결하는 방법은 무엇입니까?


21
링크가 유용 할 것입니다
another.anon.coward


1
또한 이것은 관련이있을 수 있습니다 http://mywiki.wooledge.org/BashFAQ/095
Lorenzo Belli 2016

4
@jww : bash는 오랫동안 프로그래머가 일반적으로 사용하는 소프트웨어 도구에 속한다고 생각했습니다. 여기에서 질문을 할 수있는 범주가 있습니다!
Vicky

@Nik-스크립트에 "..."를 추가하는 것은 강력하지 않습니다. 문제가 Minimal, Complete 및 Verifiable 예제 로 축소되면 명령 실행 방법에 대한 질문입니다. 내가 명백한 것을 놓친 경우 사과드립니다.
jww

답변:


876

이것이 발생하는 이유는 bash가 실제로 별표를 일치하는 모든 파일로 확장하여 매우 긴 명령 행을 생성하기 때문입니다.

이 시도:

find . -name "*.pdf" -print0 | xargs -0 rm

경고 : 이것은 재귀 검색이며 하위 디렉토리에서도 파일을 찾아 삭제합니다. 압정 -f당신은 당신이 확인을하지 않을 경우에만 rm 명령에.

다음을 수행하여 명령을 비재 귀적으로 만들 수 있습니다.

find . -maxdepth 1 -name "*.pdf" -print0 | xargs -0 rm

또 다른 옵션은 find의 -delete플래그 를 사용하는 것입니다 .

find . -name "*.pdf" -delete

7
아니요, xargs구체적으로 목록을 분할하고 필요한 경우 여러 명령을 실행합니다.
tripleee

7
@Dennis : -maxdepth 1경로 다음의 첫 번째 인수 여야합니다.
Barton Chittenden

54
Find에는 -delete찾은 파일을 삭제 하는 플래그가 있으며 -execxargs (현재는 단일 프로세스 대신 3 개의 프로세스 및 파이프 임)를 호출하는 것보다 rm을 실행 하는 것이 더 나은 방법으로 간주 됩니다. -delete또는와 2 개의 프로세스 -exec).
scragar

3
@ ÉdouardLopez ... 그러나 이것은 NULL로 구분 된 입력을 읽고 있습니다. 그리고 전체 dangerous (broken, exploitable, etc.)는 상당히 말도 안됩니다. 의심 할 여지없이 당신은 사용할 때 조심해야 xargs하지만, 그다지 아닙니다 eval/evil.
Monica State를 복원하십시오

4
@scragar을 -exec호출 하면 rm프로세스 수는 1 + 파일 수이지만 동시 프로세스 수는 2 일 수 있습니다 (rm 프로세스를 동시에 실행할 수 있음). 사용하는 프로세스 수는 xargs2 + n으로 크게 줄어 듭니다. 여기서 n은 파일 수보다 적은 수의 프로세스입니다 (예 : 경로 수에 따라 더 많지만 파일 수 / 10). find가 삭제를 직접 수행한다고 가정하면 사용 -delete하는 것이 호출되는 유일한 프로세스 여야합니다.
neuralmer

396

tl; dr

명령 행 인수의 크기에 대한 커널 제한 사항입니다. for대신 루프를 사용하십시오 .

문제의 기원

이것은 시스템 문제이며 관련이 execve있고 ARG_MAX일정합니다. 그것에 대해 문서를 많이합니다 (이 남자는 execve , 데비안의 위키 ).

기본적으로 확장 은 한계 를 초과 하는 명령 (매개 변수 포함)을 생성합니다 ARG_MAX. 커널 2.6.23에서 한계는로 설정되었습니다 128 kB. 이 상수는 증가했으며 다음을 실행하여 값을 얻을 수 있습니다.

getconf ARG_MAX
# 2097152 # on 3.5.0-40-generic

솔루션 : for루프 사용

BashFAQ / 095for 에서 권장 되는 루프를 사용 하고 RAM / 메모리 공간을 제외하고 제한이 없습니다.

드라 이런을 실행하면 예상 한 내용이 삭제됩니다.

for f in *.pdf; do echo rm "$f"; done

그리고 그것을 실행하십시오 :

for f in *.pdf; do rm "$f"; done

또한 glob가 쉘 사이에서 강력하고 일관된 동작을 갖기 때문에 이식 가능한 접근 방식 입니다 (POSIX 사양의 일부 ).

참고 : 여러 의견에서 언급했듯이 더 복잡한 시나리오 ( 예 : 하나 이상의 작업을 수행하려는 경우)를 적용 할 수 있기 때문에 실제로는 더 느리지 만 유지 관리 가 용이합니다.

솔루션 : 사용 find

주장한다면, xargs"NUL- 구분되지 않은 입력을 읽을 때 위험 (파손, 악용 가능 등)"이므로 사용할 수는 find없지만 실제로 는 사용하지 않습니다 .

find . -maxdepth 1 -name '*.pdf' -delete 

사용 -maxdepth 1 ... -delete대신하는 것은 -exec rm {} +허용 find단순히 때문에 빠르고, 외부 프로세스를 사용하지 않고 (덕분에 필요한 시스템 호출 자체를 실행하는 @chepner 주석 ).

참고 문헌


31
훌륭한 답변입니다. 이것이 모든 SO 질문에 대한 답변입니다. 감사!
tommed

1
for루프 를 언급하면 ​​+1입니다 . 나는 find이전에 사용 했지만 항상 옵션 등을 잊어 버릴 때 항상 어떻게 해야하는지 찾고 있습니다. for리콜 이럴에보다 쉽게 보인다
로버트 Dundon

3
그것은 for f in *; do rm "$f"; done매력 으로 일로 사용
abdul qayyum

3
find -exec솔루션은 훨씬 더 빨리보다 보인다 for루프.
08 분

2
5 년 후 4.15.0 ( 4.15.0-1019-gcp정확한)이고 한계는 여전히 2097152입니다. 흥미롭게도 리눅스 git repo에서 ARG_MAX를 검색하면 ARG_MAX가 131702에있는 결과를 얻을 수 있습니다.
Matt M.

181

find-delete조치를 :

find . -maxdepth 1 -name '*.pdf' -delete

4
여전히 "인수 목록이 너무 깁니다"를 반환합니다. 적어도 나에게는 그래. xargsDennis의 답변에 따라를 사용하면 의도 한대로 작동합니다.
세르지오

7
찾기 버그처럼 들립니다.
ThiefMaster

3
@Sergio는 동일한 문제가 있었는데 이름 패턴 주위에 따옴표가 없기 때문에 발생했습니다.
Luxian

아아, 왜 물건을 찾는 도구가 삭제 스위치를 가지고 있습니까? 가장 작고 위험한 말을하는 것이 불필요하다고 생각하는 사람은 저뿐입니다.
mathreadler

2
@mathreadler 일반적인 사용 사례 -exec는 많은 파일을 제거하는 것입니다. -exec rm {} +동일한 작업을 수행하지만 여전히 적어도 하나의 외부 프로세스를 시작해야합니다. 외부 래퍼를 사용하지 않고 필요한 시스템 호출 자체를 간단하게 실행할 -delete수 있습니다 find.
chepner

21

또 다른 대답은 xargs명령을 일괄 처리 하도록 강제 하는 것입니다. 예를 들어 한 번에 delete파일 100cd디렉토리에 넣고 다음을 실행하십시오.

echo *.pdf | xargs -n 100 rm


4
엔지니어이고 실수를 입력하면 Linux에서 명령을 삭제하면 재앙이 될 수 있습니다. '가장 안전하고 진행 상황을 알고 있습니다'라고 생각합니다. 당신이 유형을 그리워하면 1 분 안에 회사가 무너지게 할 것입니다 멋진 물건.
ArtificiallyIntelligence

1
특정 명령의 기본 확장을 어떻게 만들 수 있습니까? "rm"과 같이 한 번에 모두 필요로하는 경우 알려진 "표준"Linux 명령이 많이 있습니다.
user1212212

1
이것은 echo쉘 내장 위치에서만 작동합니다 . 명령을 사용 echo하면 프로그램 인수 한도에 여전히 도달하게됩니다.
Toby Speight

14

또는 시도해 볼 수 있습니다.

find . -name '*.pdf' -exec rm -f {} \;

하위 디렉토리에서도 파일이 삭제됩니다. 그것을 방지하는 방법?
Vicky

@NikunjChauhan -maxdepth 옵션 추가 :find . -maxdepth 1 -name '*.pdf' -exec rm -f {} \;
Jon Lin

maxdepth 옵션을 삽입 할 수 없습니다
Vicky

이 옵션은 위의 @Dennis의 답변 (선택된 답변)에 따라 Linux 전용 옵션 일 수 있습니다.
jvriesem

12

한 번에 매우 많은 수의 파일을 삭제하려고하면 (오늘 485,000+ 이상의 디렉토리를 삭제 한 경우) 다음 오류가 발생할 수 있습니다.

/bin/rm: Argument list too long.

문제는 당신이 무언가 같이 입력 할 때이다 rm -rf *의는 *"RF RM은 파일 1 파일 2 파일 3 file4"등등과 같은 모든 일치하는 파일의 목록으로 대체됩니다. 이 인수 목록을 저장하기 위해 할당 된 비교적 작은 메모리 버퍼가 있으며, 채워지면 쉘은 프로그램을 실행하지 않습니다.

이 문제를 해결하기 위해 많은 사람들이 find 명령을 사용하여 모든 파일을 찾고 다음과 같이 "rm"명령으로 하나씩 전달합니다.

find . -type f -exec rm -v {} \;

내 문제는 500,000 개의 파일을 삭제해야하고 너무 오래 걸리는 것입니다.

파일을 삭제하는 훨씬 빠른 방법을 발견했습니다.“find”명령에는“-delete”플래그가 내장되어 있습니다! 내가 사용한 결과는 다음과 같습니다.

find . -type f -delete

이 방법을 사용하여 초당 약 2000 파일의 속도로 파일을 삭제했습니다.

파일 이름을 삭제하면서 파일 이름을 표시 할 수도 있습니다.

find . -type f -print -delete

… 또는 삭제할 파일 수를 표시 한 다음 삭제하는 데 걸리는 시간도 표시합니다.

root@devel# ls -1 | wc -l && time find . -type f -delete
100000
real    0m3.660s
user    0m0.036s
sys     0m0.552s

감사. 나는 sudo find . -type f -delete약 485 천 개의 파일을 삭제했고 그것은 나를 위해 일했다. 약 20 초가 걸렸습니다.
Nigel Alderton

11

당신은 이것을 시도 할 수 있습니다 :

for f in *.pdf
do
  rm $f
done

편집 : ThiefMaster 의견은 나에게 그런 위험한 습관을 어린 껍질의 제디에게 공개하지 말 것을 제안합니다. 그래서 더 많은 "safer"버전을 추가 할 것입니다 (누군가 "-rf. ..pdf"파일이있을 때 물건을 보존하기 위해)

echo "# Whooooo" > /tmp/dummy.sh
for f in '*.pdf'
do
   echo "rm -i $f" >> /tmp/dummy.sh
done

위를 실행 한 후 즐겨 찾기에서 /tmp/dummy.sh 파일을여십시오. 편집기에서 모든 한 줄에 위험한 파일 이름이 있는지 확인하고 발견되면 주석 처리하십시오.

그런 다음 작업 디렉토리에 dummy.sh 스크립트를 복사하여 실행하십시오.

보안상의 이유로이 모든 것.


5
나는 이것이 예를 들어 파일 이름으로 정말 좋은 일을 할 것이라고 생각합니다-rf .. .pdf
ThiefMaster

그렇다. 그러나 일반적으로 쉘에서 사용될 때, ""명령을 내리는 사람은 자신이 무엇을하고 있는지 살펴보아야한다.) 실제로 파일로 리디렉션 한 다음 모든 단일 행을 검사하는 것을 선호합니다.
BigMike

2
"$ f"는 인용하지 않습니다. 그것이 ThiefMaster가 말한 것입니다. -rf보다 우선 -i하므로 두 번째 버전은 더 이상 나쁘지 않습니다 (수동 검사없이). 그리고 기본적으로 모든 파일에 대한 프롬프트 때문에 대량 삭제에는 쓸모가 없습니다.
Peter Cordes

7

bash 배열을 사용할 수 있습니다 :

files=(*.pdf)
for((I=0;I<${#files[@]};I+=1000)); do
    rm -f "${files[@]:I:1000}"
done

이렇게하면 단계 당 1000 개 파일 씩 삭제됩니다.


2
많은 파일의 경우이 속도가 훨씬 빠릅니다.
James Tocknell


4

은 rm 명령을 동시에 제거 할 수있는 파일의 제한이 있습니다.

rm 명령 을 여러 번 사용 하여 파일 패턴을 기반으로 파일 패턴을 제거 할 수 있습니다 .

rm -f A*.pdf
rm -f B*.pdf
rm -f C*.pdf
...
rm -f *.pdf

find 명령을 통해 제거 할 수도 있습니다 .

find . -name "*.pdf" -exec rm {} \;

3
아니요, rm처리 할 파일 수에 대한 제한은 없습니다 ( argc이보다 클 수 없음 INT_MAX). 그것은 전체 인수 배열 의 최대 크기에 대한 커널의 제한입니다 (그래서 파일 이름의 길이가 중요합니다).
Toby Speight

3

공백이나 특수 문자가 포함 된 파일 이름 인 경우 다음을 사용하십시오.

find -maxdepth 1 -name '*.pdf' -exec rm "{}" \;

이 문장은 현재 디렉토리 (-maxdepth 1)에서 확장자가 pdf (-name '* .pdf') 인 모든 파일을 검색 한 다음 각 파일 (-exec rm "{}")을 삭제합니다.

{} 표현식은 파일 이름을 대체하고 "{}"은 공백 또는 특수 문자를 포함하여 파일 이름을 문자열로 설정합니다.


이 코드는에 대한 설명을 포함하여 문제 해결 수 있지만 방법이유를 이 해결할 수있는 문제가 문제가 정말 도움이 될 게시물의 품질을 향상시킬 수 있습니다. 지금 질문하는 사람뿐만 아니라 앞으로 독자들에게 질문에 대답하고 있음을 기억하십시오! 제발 편집 설명을 추가하고, 제한 및 가정이 적용 무엇의 표시를 제공하는 답변을.
Toby Speight

요점은 -exec쉘을 호출하지 않는다는 것입니다. 여기 인용문은 전혀 유용하지 않습니다. ( 이 명령을 입력 한 쉘 의 문자열 에서 와일드 카드 확장 및 토큰 분할을 방지 하지만 문자열에 {}공백 또는 쉘 와일드 카드 문자가 포함되어 있지 않습니다.)
tripleee

2

양식 소스 디렉토리를 대상으로 복사하는 동안 동일한 문제가 발생했습니다.

소스 디렉토리에 파일이 ~ 3 lakcs

나는 옵션 -r함께 cp를 사용 했고 그것은 나를 위해 일했다.

cp -r abc / def /

인수 목록에 대한 경고없이 경고없이 abc에서 def로 모든 파일을 복사합니다.


나는 누군가가 그것에 대해 언급하지 않고 왜 이것을 하향 조정했는지 알지 못합니다 (정책, 사람들입니다!). 폴더 내부의 모든 파일을 삭제해야했습니다 (질문은 PDF에 관한 것이 아닙니다). . 나는`RM -R / 경로 /로 / 폴더 "사용
토마스 TEMPELMANN

1
OP의 경우에는 *를 사용하고 있기 때문에 큰 .pdf 목록으로 확장되어 디렉토리를 제공하면 디렉토리가 내부적으로 처리되므로 OP의 문제를 처리하지 않아도됩니다. 그 이유 때문에 다운 보트 된 것 같습니다. 디렉토리에 디렉토리 나 다른 파일 (pdf가 아님)이 중첩되어 있으면 OP에 사용할 수 없습니다.
Alvein

2

30/90 일 이상 (+) 또는 30/90 (-) 일 미만의 파일 / 폴더를 삭제하려면 아래 ex 명령을 사용할 수 있습니다

예 : 90 일 동안 파일 / 폴더 삭제 후 90 일을 제외하면 91,92 .... 100 일을 의미합니다.

find <path> -type f -mtime +90 -exec rm -rf {} \;

예 : 삭제하려는 최신 30 일 파일의 경우 아래 명령 (-)을 사용하십시오

find <path> -type f -mtime -30 -exec rm -rf {} \;

2 일 이상 동안 파일을 가져 오려면

find <path> -type f -mtime +2 -exec gzip {} \;

지난 1 개월 동안 만 파일 / 폴더를 보려면. 전의:

find <path> -type f -mtime -30 -exec ls -lrt {} \;

30 일 이상 동안 만 파일 / 폴더를 나열하십시오. 예 :

find <path> -type f -mtime +30 -exec ls -lrt {} \;

find /opt/app/logs -type f -mtime +30 -exec ls -lrt {} \;

2

ulimit여기에 답 이 없다는 것에 놀랐습니다 . 이 문제가 생길 때마다 나는 여기 또는 여기에서 끝납니다 . 이 솔루션에는 한계가 있지만 ulimit -s 65536종종 나를 위해 속임수를 쓰는 것으로 알고 있습니다.


1

매일 증가하는 임시 이미지로 가득 찬 폴더에 동일한 문제가 있었고이 명령으로 폴더를 지우는 데 도움이되었습니다.

find . -name "*.png" -mtime +50 -exec rm {} \;

다른 명령과의 차이점은 X 일보다 오래된 파일 만 가져 오는 mtime 매개 변수입니다 (예 : 50 일)

여러 번 사용하여 하루 범위마다 실행을 줄이면 불필요한 파일을 모두 제거 할 수있었습니다.


1

나는 이것에 대한 길을 알고 있습니다. 아이디어는 해당 pdf 파일 목록을 파일로 내보내는 것입니다. 그런 다음 해당 파일을 여러 부분으로 분할하십시오. 그런 다음 각 부분에 나열된 pdf 파일을 제거하십시오.

ls | grep .pdf > list.txt
wc -l list.txt

wc -l은 list.txt에 포함 된 행 수를 계산하는 것입니다. 당신이 그것이 얼마나 긴지에 대한 아이디어가있을 때, 당신은 그것을 반으로 나누거나 다른 것으로 나누기로 결정할 수 있습니다. split -l 명령 사용 예를 들어, 각각 600 줄로 분할하십시오.

split -l 600 list.txt

이렇게하면 xaa, xab, xac라는 이름의 파일이 생성되므로 분할 방법에 따라 다릅니다. 이제 해당 파일의 각 목록을 명령 rm으로 "가져 오려면"다음을 사용하십시오.

rm $(<xaa)
rm $(<xab)
rm $(<xac)

내 하찮은 영어 실력에 죄송하다는 말씀을 드리고 싶습니다.


5
당신이 파일을 가지고 있다면 pdf_format_sucks.docx이것도 역시 삭제 될 것입니다; ;-) pdf 파일들을 grepping 할 때 적절하고 정확한 정규식을 사용해야합니다.
FooF

1
더 좋지만 still_pdf_format_sucks.docx삭제됩니다. 정규식 의 점 .".pdf"모든 문자와 일치합니다. "[.]pdf$"대신에 제안 합니다 .pdf.
FooF

1

나는이 문제에 몇 번 부딪쳤다. 많은 솔루션이 rm삭제해야하는 각 개별 파일에 대해 명령을 실행합니다 . 이것은 매우 비효율적입니다.

find . -name "*.pdf" -print0 | xargs -0 rm -rf

파일 이름의 처음 4자를 기반으로 파일을 삭제하기 위해 파이썬 스크립트를 작성했습니다.

import os
filedir = '/tmp/' #The directory you wish to run rm on 
filelist = (os.listdir(filedir)) #gets listing of all files in the specified dir
newlist = [] #Makes a blank list named newlist
for i in filelist: 
    if str((i)[:4]) not in newlist: #This makes sure that the elements are unique for newlist
        newlist.append((i)[:4]) #This takes only the first 4 charcters of the folder/filename and appends it to newlist
for i in newlist:
    if 'tmp' in i:  #If statment to look for tmp in the filename/dirname
        print ('Running command rm -rf '+str(filedir)+str(i)+'* : File Count: '+str(len(os.listdir(filedir)))) #Prints the command to be run and a total file count
        os.system('rm -rf '+str(filedir)+str(i)+'*') #Actual shell command
print ('DONE')

이것은 나를 위해 아주 잘 작동했습니다. 약 15 분 안에 폴더에서 2 백만 개가 넘는 임시 파일을 지울 수있었습니다. 파이썬에 대한 지식이 거의없는 사람이라면 누구나이 코드를 조작 할 수 있도록 약간의 코드에서 tar를 주석 처리했습니다.


1

그리고 또 하나 :

cd  /path/to/pdf
printf "%s\0" *.[Pp][Dd][Ff] | xargs -0 rm

printf셸 내장이며, 내가 아는 한 항상 그렇습니다. 이제는 printf이것이 쉘 명령 (그러나 내장)이 아니라면 argument list too long ...치명적인 오류에 영향을받지 않습니다 .

우리가 안전하게 같은 쉘 글 로빙 패턴으로 사용할 수 있도록 *.[Pp][Dd][Ff], 제거하려면 우리 파이프 출력 ( rm) 명령을 통해 xargs어떤을 만들고, 반드시 그렇게으로 실패하지 않는 명령 행에 충분한 파일 이름에 맞는 rm쉘은 명령을 명령.

\0에서 printf다음으로 처리 느릅 파일 이름 널 분리기로서 기능 xargs을 사용 명령 ( -0) 세퍼레이터로서 매우 rm공백이나 파일명의 기타 특수 문자가있을 때하지 않는다.


1
이 코드는에 대한 설명을 포함하여 문제 해결 수 있지만 방법이유를 이 해결할 수있는 문제가 문제가 정말 도움이 될 게시물의 품질을 향상시킬 수 있습니다. 지금 질문하는 사람뿐만 아니라 앞으로 독자들에게 질문에 대답하고 있음을 기억하십시오! 제발 편집 설명을 추가하고, 제한 및 가정이 적용 무엇의 표시를 제공하는 답변을.
Toby Speight

특히, printf셸 내장이 아닌 경우 동일한 제한이 적용됩니다.
Toby Speight

0

임시 폴더를 만들고 임시 폴더로 유지하려는 모든 파일과 하위 폴더를 옮긴 다음 이전 폴더를 삭제하고 임시 폴더의 이름을 이전 폴더로 바꿀 수 있습니다.

mkdir testit
cd testit
mkdir big_folder tmp_folder
touch big_folder/file1.pdf
touch big_folder/file2.pdf
mv big_folder/file1,pdf tmp_folder/
rm -r big_folder
mv tmp_folder big_folder

rm -r big_folder파일 수에 big_folder관계없이 모든 파일을 제거합니다 . 먼저 보관하려는 모든 파일 / 폴더가 있는지주의해야합니다.이 경우에는file1.pdf


0

*.pdf디렉토리에서 모두 삭제하려면/path/to/dir_with_pdf_files/

mkdir empty_dir        # Create temp empty dir

rsync -avh --delete --include '*.pdf' empty_dir/ /path/to/dir_with_pdf_files/

rsync와일드 카드 를 사용하여 특정 파일을 삭제하는 것은 수백만 개의 파일이있는 경우 가장 빠른 해결책 일 것입니다. 그리고 그것은 당신이 받고있는 오류를 처리합니다.


(선택적 단계) : DRY RUN. 삭제하지 않고 삭제할 내용을 확인합니다. `

rsync -avhn --delete --include '*.pdf' empty_dir/ /path/to/dir_with_pdf_files/

. . .

더 많은 rsync 해킹을 위해 rsync 팁과 요령 을 클릭하십시오.


0

매우 큰 파일 목록 (> 1e6)의 경우 이러한 답변이 너무 느립니다. 다음은 파이썬에서 병렬 처리를 사용하는 솔루션입니다. 나는 이것이 리눅스가 아니라는 것을 알고 있지만 여기서는 아무것도 작동하지 않았다.

(시간이 절약되었습니다)

# delete files
import os as os
import glob
import multiprocessing as mp

directory = r'your/directory'
os.chdir(directory)


files_names = [i for i in glob.glob('*.{}'.format('pdf'))]

# report errors from pool

def callback_error(result):
    print('error', result)

# delete file using system command
def delete_files(file_name):
     os.system('rm -rf ' + file_name)

pool = mp.Pool(12)  
# or use pool = mp.Pool(mp.cpu_count())


if __name__ == '__main__':
    for file_name in files_names:
        print(file_name)
        pool.apply_async(delete_files,[file_name], error_callback=callback_error)

0

모든 inode를 채운 응용 프로그램으로 만든 수백만 개의 쓸모없는 로그 파일이있을 때 비슷한 문제에 직면했습니다. "locate"에 의지하여 모든 파일을 텍스트 파일에 "located"한 다음 하나씩 제거했습니다. 시간이 걸렸지 만 일을 했어요!


이것은 매우 모호하며 locate디스크에 여유 공간이있을 때 다시 설치해야합니다 .
tripleee

-2

xargs를 사용하는 것보다 조금 더 안전한 버전도 재귀 적이 지 않습니다. ls -p | grep -v '/$' | grep '\.pdf$' | while read file; do rm "$file"; done

'rm'은 어쨌든 삭제하지 않기 때문에 디렉토리를 필터링하면 약간 불필요하며 간단하게 제거 할 수는 있지만 오류를 반환하는 무언가를 실행하는 이유는 무엇입니까?


3
이것은 전혀 안전하지 않으며 개행 문자가있는 파일 이름으로는 작동하지 않으므로 한 가지 확실한 경우가 있습니다. 구문 분석ls 은 반드시 피해야하는 일반적인 반 패턴이며 여기에 여러 가지 버그가 추가됩니다. 은 grep | grep단지 매우 우아하지 않습니다.
tripleee

어쨌든 복잡한 솔루션이 필요한 새롭고 이국적인 문제는 아닙니다. 대답 find은 훌륭하고 여기 및 다른 곳에 잘 기록되어 있습니다. 이 주제와 관련 주제에 대한 자세한 내용은 mywiki.wooledge.org 를 참조하십시오 .
tripleee

-2

GNU 병렬 ( sudo apt install parallel)을 사용하는 것은 매우 쉽다

'{}'이 (가) 전달 된 인수 인 경우 다중 스레드 명령을 실행합니다.

예 :

ls /tmp/myfiles* | parallel 'rm {}'


잘 모르겠지만 ls다른 명령 으로 직접 출력 하는 것은 위험한 반 패턴 이기 때문에 와일드 카드의 확장으로 인해 ls원래 rm명령 에서 경험 한 것처럼 실행시 동일한 오류가 발생한다는 사실을 알 것입니다. .
Toby Speight

이에 대한 내용은 ParsingLs를 참조하십시오 . 그리고 parallel당신은 후드 아래에 보면, 꽤 불투명입니다 - 불편 복잡성을 피하고 선호하는 몇몇 사람을 만든다. Stephane ( Unix & Linux StackExchange greybeards 중 하나 )과 Ole Tange (Parallel의 저자) 사이에 있는 list.gnu.org/archive/html/bug-parallel/2015-05/msg00005.html 의 메일 링리스트 스레드를 참조하십시오 . 또한 병렬화되지만, 움직이는 부분이 적어 더 단순하고 어렴풋한 방식으로 동작을 예측하고 추론하기가 훨씬 쉽습니다. xargs -P
찰스 더피

-2

처음 100 개 파일 제거 :

rm -rf 'ls | 머리 -100 '


2
위험합니다 (또는 분명하게 의도 한대로 역 따옴표를 사용한 경우). 파일 이름에 공백을 포함한 쉘 메타 문자가 포함 된 경우 결과는 의도 한 것과 다릅니다.
Toby Speight

-5

아래 옵션은이 문제에 간단합니다. 다른 스레드 에서이 정보를 얻었지만 도움이되었습니다.

for file in /usr/op/data/Software/temp/application/openpages-storage/*; do
    cp "$file" /opt/sw/op-storage/
done

위의 명령 하나만 실행하면 작업이 수행됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.