답변:
파일을 삭제하는 방법에 대한 질문은 신중하게 처리해야한다는 것을 알고 있습니다. 내 첫 번째 대답은 너무 성급해서 파일 목록이 egrep과 함께 사용하기 위해 형식이 잘못되었다는 사실을 이해하지 못했습니다. 그 위험을 줄이기 위해 답을 편집했습니다.
이름에 공백이없는 파일에 대해서는 작동합니다.
먼저 정확한 파일 이름과 일치하도록 파일 목록을 다시 작성하십시오.
sed -e 's,^,^,' -e 's,$,$,' filelist > newfilelist
rm 명령을 빌드하십시오
cd your_directory
ls | egrep -vf newfilelist | xargs -n 1 echo rm > rmscript
rm 스크립트가 적합한 지 확인하십시오 ( "vim"또는 "less"로 수행 할 수 있음).
그런 다음 작업을 수행하십시오.
sh -x rmscript
파일 이름에 공백이 있으면 파일 이름에 공백이 있으면 "
작동하지 않습니다.
ls | egrep -vf newfilelist | sed 's,^\(.*\)$,rm "\1",' > rmscript
물론 파일 목록은 같은 디렉토리에 있어서는 안됩니다!
편집 :
Nathan의 파일 목록에는 디렉토리의 모든 파일과 일치하는 이름이 포함되어 있습니다 (예 : "html"은 "bob.html"과 일치). egrep -vf
모든 스트림을 흡수 했기 때문에 삭제 된 것이 없습니다 . 각 파일 이름 주위에 "^"와 "$"를 넣는 명령을 추가했습니다. 나는 Nathan의 파일 목록이 정확하다는 것이 운이 좋았습니다. CR-LF로 끝나는 줄이나 추가 공백으로 DOS 형식이 되었습니까? egrep에 의해 파일이 보존되지 않았으며 모두 삭제되었습니다.
ls
디렉토리 파일 이름을 제공하고 egrep -vf filelist
50 파일 이름을 필터링하십시오. 모든 파일을 삭제 한 것 같습니다.
다음에 대한 인수를 사전 구성하십시오 find
.
{
read -r
keep=( -name "$REPLY" ) # no `-o` before the first one.
while read -r; do
keep+=( -o -name "$REPLY" )
done
} < file_list.txt
find . -type f ! \( "${keep[@]}" \) -exec echo rm {} +
echo
부품을 사용하여 구성 내용을 확인하십시오. echo
실제로 실행할 부품을 제거하십시오 .
##
# Demonstrate what files exist for testing.
# Show their whitespace:
~/foo $ printf '"%s"\n' *
" op"
" qr"
"abc"
"def"
"gh "
"ij "
"k l"
"keep"
"m n"
##
# Show the contents of the "keep" file,
# Including its whitespace:
~/foo $ cat -e keep
keep$
abc$
gh $
k l$
op$
##
# Execute the script:
~/foo $ { read -r; keep=( -name "$REPLY" ); while read -r ; do keep+=( -o -name "$REPLY" ); done } < keep
~/foo $ find . -type f ! \( "${keep[@]}" \) -exec rm {} +
##
# Show what files remain:
~/foo $ printf '"%s"\n' *
" op"
"abc"
"gh "
"k l"
"keep"
'
)를 추가해야 합니다 ( 예 : keep=( -name \'"$REPLY"\' )
및) keep+=( -o -name \'"$REPLY"\' )
.
로 zsh
:
mylist=(${(f)"$(<filelist)"})
print -rl -- *(.^e_'(($mylist[(Ie)$REPLY]))'_)
filelist
배열 의 행을 읽은 다음 glob 한정자 / e
문자열 을 사용 하여 배열에없는 파일 이름 만 glob / 선택합니다. .
일반 파일 만 선택하고 ( D
목록에 dotfile이 포함 된 경우 추가 ) 부정 ^e_'expression'_
된 항목은 어떤 식 반환 거짓, 즉 자신의 이름 (있는 경우 $REPLY
) 배열의 요소가 아니다 .
당신이 결과에 만족하는 경우 교체 print -rl
와 rm
실제로 파일을 제거하려면 :
rm -- *(.^e_'(($mylist[(Ie)$REPLY]))'_)
재귀 적으로 파일을 선택하고 제거하려면 glob 수정 자 */**
와 함께 ${REPLY:t}
glob를 사용하십시오 .
rm -- */**(.^e_'(($mylist[(Ie)${REPLY:t}]))'_)
디렉토리의 내용을 파일에 넣으면 다음과 같습니다.
cd <somedirectory>
ls >> filelist
텍스트 편집기와 파일 목록 및 제외한 모든 파일을 제거 삭제할을 . 위의 답변에 반대되는 접근 방식이므로 대담합니다.
이 시도:
while read p || [[ -n $p ]];
echo $p
done < filelist
화면에 출력 된 파일 목록이 표시되면 다음과 rm -v
같이 echo를로 바꾸십시오 .
while read p || [[ -n $p ]];
rm -v $p
done < filelist
아래 스크립트를 실행하십시오.
all_files
.not_to_be_deleted_files
).not_to_be_deleted_files
과
files_to_be_deleted
끝에 추가하고 not_to_be_deleted_files
있습니다.join
명령을 사용하여 삭제 해야하는 파일을 찾고
출력을 files_to_be_deleted
파일로 리디렉션 합니다.files_to_be_deleted
언급 된 파일을 제거합니다.스크립트는 다음과 같습니다.
find /home/username/directory -type f | sed 's/.*\///' > all_files
echo all_files >> not_to_be_deleted_files
echo not_to_be_deleted_files >> not_to_be_deleted_files
echo files_to_be_deleted >> not_to_be_deleted_files
join -v 1 <(sort all_files_listed) <(sort files_not_to_be_deleted) > files_to_be_deleted
while read file
rm "$file"
done < files_to_be_deleted
추신 : 아마도 이것을 스크립트로 저장하고 실행하려면을 사용하여 스크립트 이름을 추가 할 수 있습니다 echo scriptname >> not_to_be_deleted_files
.
꼭 필요한 것은 아니지만 나중에 후회하지 않기 때문에 선호합니다. 작은 파일 세트를 테스트했으며 시스템에서 작동했습니다. 그러나 확실하게하려면 test
먼저 디렉토리 에서 시도한 다음 원래 디렉토리에서 파일을 제거하십시오.
나는 목록에 18.000 개의 파일이 있기 때문에 더 안전하고 훨씬 더 빠른 접근 방식을 찾았습니다! 대규모 Drupal 설치에서 이미지를 정리해야했습니다.
목록에없는 모든 파일을 삭제하는 것은 목록에있는 파일 만 유지하는 것과 같습니다. 그래서 실제로 파일을 목록에서 다른 위치로 복사하기로 결정했지만 20GB의 파일을 복사하면 공간이 너무 많이 걸리고 매우 느려집니다. 트릭은 옵션을 hardlinks
사용하여 대신 파일을 복사 하는 -l
것입니다 cp
. 이것은 거의 공간을 차지하지 않으며 매우 빠릅니다. 또한 디렉토리 구조를 유지해야했기 때문에 --parents
옵션을 사용했습니다 .
내 파일 목록에서 발췌 한 내용은 다음과 같습니다.
1px.png
misc/feed.png
modules/file/icons/x-office-presentation.png
modules/file/icons/x-office-spreadsheet.png
newsletter.png
sites/all/libraries/ckeditor/plugins/smiley/images/devil_smile.png
sites/all/libraries/ckeditor/plugins/smiley/images/regular_smile.png
sites/default/files/009313_PwC_banner_CBS_Observer_180x246px.jpg
예를 들어 temp는 대상입니다.
cp -l --parents 'misc/feed.png' temp
이것은이 구조를 만들 것입니다 :
temp
misc
feed.png
대상은 소스와 동일한 파일 시스템에 있어야 하드 링크가 작동합니다.
다음 단계는 스크립트를 구성하는 것입니다.
sed -e "s,^,cp -l --parents '," -e "s,$,' /some/where/temp," filelist > newfilelist
이제 빈 디렉토리 / some / where / temp를 이미 만들었다 고 가정하면 다음과 같이 파일을 복사 할 수 있습니다.
sh newfilelist 2> missing_files
에서 오류가 어떻게 발생하는지 확인하십시오 missing_files
. 이 방법의 추가 보너스는 실제로 원래 목록에서 파일 목록을 얻는다는 것입니다 존재 하지 않는 !
스크립트를 실행 한 후 temp에는 파일 목록에있는 파일 만 포함되지만 아무것도 삭제하지 않고 추가 공간을 차지하지 않습니다. 결과에 만족하면 하위 폴더를 포함하여 모든 원본 파일을 삭제할 수 있습니다.
마지막으로 파일과 폴더를 임시 위치에서 원래 위치로 다시 이동하십시오.
18.000 파일의 경우 몇 초 밖에 걸리지 않았습니다.
안전하고 간단합니다.
cd
디렉토리에.
임시 디렉토리를 작성하십시오.
mv *.yourExlusionSelector.* ./temp
rm *
mv ./temp ./
rm -rf ./temp
끝난.