2012-09-29 2 views
5

나는 UNIX에 소개 코스를 다음과 숙제 질문이 있어요 :Bash에서 사람이 읽을 수있는 파일을 모두 계산하는 방법은 무엇입니까?

얼마나 많은 파일 앞의 질문에서 텍스트 파일을? 텍스트 파일은 사람이 읽을 수있는 내용이 포함 된 파일입니다. (TRICK 질문입니다. 파일이 텍스트 파일이나 이진 데이터 파일이 있는지 여부를 확인하기 위해 파일에서 파일 명령을 실행하십시오! 당신은 단순히 당신이이 질문에 대한 더 포인트를 얻을 것이다 .txt 확장자를 가진 파일의 수를 계산합니다.)

이전 질문에는 단순히 몇 개의 일반 파일이 있었는지 묻는 질문이있었습니다. find . -type f | wc -l을 통해 쉽게 알아낼 수있었습니다.

"사람이 읽을 수있는 콘텐츠"가 무엇인지 결정하는 데 문제가 있습니다. 바이너리/어셈블리 외에 다른 것을 의미한다고 가정하고 있기 때문에 문제가 있습니다.하지만 그게 -type f입니다. 어쩌면 교수가 "트릭 질문"이라고 말한 것일 수도 있습니다.

이 질문은 "어떤 텍스트 파일에 대문자와 소문자를 혼합하여"csc "문자열이 포함되어 있는지 묻습니다." 분명히 "텍스트"는 단지 .txt 개 이상의 파일을 가리키고 있습니다. 그러나 이것을 결정하는 첫 번째 질문을 찾아야합니다! 명확성을 위해 추가

+1

아니요, find -type f는 디렉토리, 장치 노드 등을 제외합니다. ("투기 ial files ") 즉, 순수 파일 이외의 파일 시스템 객체를 포함 할 수있다. 파일 내용을 전혀 검사하지 않고 디렉토리 항목 (inode)의 유형 정보 만 검사합니다. 유닉스는 "바이너리"와 "텍스트"파일을 구별하지 않는다. (그리고이 유닉스 머리에서는 이러한 구별을 정의하려는 시도가 미끄러운 경사면에 들어간다.) – tripleee

답변

6

지수 :

이 파일을 텍스트 파일이나 이진 데이터 파일이 있는지 여부를 확인하기 위해 파일의 "파일"명령을 실행!

file 명령은 파일을 검사하여 파일의 종류를 알려줍니다. "text"라는 단어는 텍스트 파일에 대한 설명에 항상 (거의) 포함됩니다. 예를 들어

:

desktop.ini: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators 
tw2-wasteland.jpg: JPEG image data, JFIF standard 1.02 

그래서 첫 번째 부분은 file 명령을 실행하고 출력을 구문 분석을 요구하고있다.

"사람이 읽을 수있는 콘텐츠"가 무엇인지 결정하는 데 문제가 있습니다. 바이너리/어셈블리 외에 다른 것을 의미한다고 가정하고 있기 때문에 문제가 있습니다.하지만이게 형식 -f가 표시하는 것입니다.

find -type f 파일을 찾습니다. 디렉토리, 심볼릭 링크, 소켓과 같은 다른 파일 시스템 객체를 걸러냅니다. 바이너리 파일, 텍스트 파일, 그 밖의 모든 파일 유형과 일치합니다.

아마도 교수가 "트릭 질문"이라고 말한 것일 수 있습니다.

그는 그냥 텍스트 파일을 찾기 위해 find -name '*.txt'이나 그런 명령을 사용하지 않는다고 말하는 것 같습니다. 특정 파일 확장자를 가정하지 마십시오. 파일 확장자는 Windows에서보다 UNIX에서의 의미가 훨씬 적습니다. 파일을 많이 심지어 파일 확장자가 없습니다! 나는 교수를 생각하고


은 우리가 모든 파일에 파일 명령을 실행하고있는 '텍스트'와 사람의 수를 계산 할 수 있도록하고자합니다.

여러 부분으로 구성된 답변은 어떻습니까? 아마도 교수님이 찾고있는 # 1에서 간단한 해결책을 제시 할 것입니다. 관심이 있으시면 그 단점과 개선 방법에 대해 설명하겠습니다.

  1. 한 가지 방법은 그것에 대해 배웠다면 xargs을 사용하는 것입니다. xargs은 명령의 인수로 stdin의 데이터를 사용하여 다른 명령을 실행합니다.

    $ find . -type f | xargs file 
    ./netbeans-6.7.1.desktop: ASCII text 
    ./VMWare.desktop:   a /usr/bin/env xdg-open script text executable 
    ./VMWare:     cannot open `./VMWare' (No such file or directory) 
    (copy).desktop:   cannot open `(copy).desktop' (No such file or directory) 
    ./Eclipse.desktop:  a /usr/bin/env xdg-open script text executable 
    
  2. 그게 작동합니다. 일종의. 숙제를하기에 충분할거야. 그러나 현실 세계의 대본에는 충분하지 않습니다.

    VMWare (copy).desktop에 공백이 있으므로 파일이 어떻게 손상되었는지 유의하십시오. 이는 공백에 인수를 분할하는 xargs의 기본 동작 때문입니다. 우리는 xargs -0을 사용하여 공백 대신 NUL 문자에 명령 인수를 나눌 수 있습니다. 파일 이름에는 NUL 문자가 포함될 수 없으므로이 문자는 아무 것도 처리 할 수 ​​없습니다.

    $ find . -type f -print0 | xargs -0 file 
    ./netbeans-6.7.1.desktop: ASCII text 
    ./VMWare.desktop:   a /usr/bin/env xdg-open script text executable 
    ./VMWare (copy).desktop: a /usr/bin/env xdg-open script text executable 
    ./Eclipse.desktop:  a /usr/bin/env xdg-open script text executable 
    
  3. 이것은 생산 스크립트에 대한 충분하고, 당신이 많이 발생하는 것입니다 무언가이다. 그러나 개인적으로 파이프가 필요없는 대체 구문을 선호하므로 약간 더 효율적입니다.

    $ find . -type f -exec file {} \; 
    ./netbeans-6.7.1.desktop: ASCII text 
    ./VMWare.desktop:   a /usr/bin/env xdg-open script text executable 
    ./VMWare (copy).desktop: a /usr/bin/env xdg-open script text executable 
    ./Eclipse.desktop:  a /usr/bin/env xdg-open script text executable 
    

    는 것을 이해하기 -exec 찾은 각 파일 이름으로 {} 교체, 반복 file를 호출합니다. 세미콜론 \;file 명령의 끝을 표시합니다.

+0

분명히 "사람이 읽을 수있는"이란 파일의 것이 아니라 사람의 기능입니다. 나는 README라는 파일 대부분이 실제로 대부분의 사람이 읽을 수 없다는 강한 인상을 항상 가지고있었습니다. – rici

+0

도움 주셔서 감사합니다. 그 파일이 파일이 '텍스트'파일인지 아닌지를 판단 할 수 있지만, 정규 파일을 찾는 것과 관련된 첫 번째 질문의 최종 결과는 153 개의 파일 (그 디렉토리 우리가 작업하고있는 하위 디렉토리로 가득 찼습니다.) 교수는 우리가 모든 파일에 대해 파일 명령을 실행하고 '텍스트'가 포함 된 파일 수를 계산할 수 있기를 바랍니다.그럴 가능성이 있다고 가정하면 어떻게 할 것인가? – Rekson

+0

@ user1687406'find '와'file'을 결합하는 것에 대한 (지나치게) 상세한 설명으로 나의 대답을 업데이트했습니다. 나는 출력을'grep '하는 방법에 가지 않았다. 도움이 필요하시면 알려주세요. –

0

이 파일은 사람이 읽을 수있는 텍스트 파일인지 확인 만 file --mime-type <filename>를 사용하고 'text/plain'를 찾을 수있는 좋은 쉬운 방법이있다. 파일이 결말이 있거나 .txt로하는 다른 결말을 가지고 있다면 상관없이 작동합니다

그래서 당신은 할 것 STH 같은 :

FILES=`find $YOUR_DIR -type f` 

for file in $FILES ; 
do 

mime=`/usr/bin/file --mime-type $YOUR_DIR/$file | /bin/sed 's/^.* //'` 

if [ $mime = "text/plain" ]; then  
    fileTotal=$((fileTotal + 1)) 
    echo "$fileTotal - $file" 
fi 

done 

echo "$fileTotal human readable files found!" 

및 출력 STH 좋아하는 것 :

1 - /sampledir/samplefile 
2 - /sampledir/anothersamplefile 
.... 
23 human readable files found! 

사람이 읽을 수있는 MIME 형식을 더 많이 사용하려면 (예 : HTML 및/또는 XML 개수가?) http://www.feedforall.com/mime-types.htm

관련 문제