목록에서 대화식으로 파일 삭제 이유는 무엇입니까? while read

파일 목록을 제거하고 확인을 요청하고 싶습니다. 목록은 list.txt파일에 있습니다. 다음 명령이 제대로 작동하지 않는 이유는 무엇입니까?

while read i; do rm -i $i; done < list.txt

이전 명령은 나를 기다리지 않지만 다행히 파일이 삭제되지 않습니다.

Bash를 사용하고 있습니다.



답변

rm -iwhile루프 에서 상속되는 표준 입력에서 응답을 읽습니다 . 따라서 list.txt“정말로 삭제 하시겠습니까?”에 대한 답변으로 한 줄의 텍스트 가 사용되고 있습니다. 질문. 수정하려면 두 가지 입력 소스를 분리해야합니다. 가장 쉬운 방법은 read별도의 파일 설명자에서 입력을받는 것입니다.

while IFS= read <&3 -r i; do
  rm -i -- "$i"     # Quote the file name, not just to be safe,
                    # but because it's the right syntax.
done 3< list.txt

while 루프의 표준 입력 (fd 0)을 더 이상 리디렉션하지 않으므로 rm원하는대로 터미널에서 읽습니다.

또는 다음을 수행 할 수 있습니다.

IFS=$'\n' # set field separator to newline
set -f    # disable globbing upon command substitution
rm -i -- $(cat list.txt)

또는 GNU xargs를 사용하는 경우 :

xargs -rd '\n' --arg-file=list.txt rm -i --


답변

각 파일에 예 또는 아니오로 응답하는 것보다 조금 더 멋진 경우 iselect대화식 ncurses 기반 선택에 사용할 수 있습니다 . 예 :

iselect -a -m < list.txt | xargs -d '\n' -r echo rm 

또는 현재 디렉토리에서 파일 선택을 허용하려면 다음을 수행하십시오.

find . -maxdepth 1 -type f | iselect -a -m | xargs -d '\n' -r echo rm

그러면 SPACE를 눌러 파일을 마음대로 선택 및 선택 해제 할 수있는 전체 화면 (전체 터미널) ncurses 기반 목록이 표시됩니다. ENTER를 눌러 선택 사항을 승인하거나 (선택한 항목은 stdout에 인쇄 됨) q종료합니다 ( stdout에 인쇄 된 항목 없음). h도움을 받으려면을 누르십시오 .

참고 echo rm-테스트 용으로 작성했습니다. rm자신이하는 일을 이해하고 있다고 확신하면 변경하십시오 .

또한 xargs여기서는 \n입력 분리 자로 사용됩니다 . 파일 이름에 줄 바꿈 문자가있는 파일은 작동하지 않습니다. 그 문제에 관해서 iselect는 올바르게 작동 iselect하지 않습니다. 행 당 하나의 항목을 기대합니다-불행히도 null로 끝나는 입력 또는 출력 옵션이 없습니다.

iselect데비안, 우분투 및 기타 배포판 용으로 패키지되어 있습니다. 홈페이지는 http://www.ossp.org/pkg/tool/iselect/ 에 있습니다 .


답변