2012-09-29 11 views
5

私はUNIXにイントロのコースを取って、次の宿題の質問持っている:以前の問題のファイルはテキストファイルですどのように多くの人間が読めるBashですべてのファイルを数えるには?

を?テキストファイルとは、人間が読める形式のファイルです。 (TRICK QUESTION。ファイル上でfileコマンドを実行すると、そのファイルがテキストファイルかバイナリデータファイルかを確認できます).txt拡張子のファイル数を数えるだけであれば、この質問のポイントは得られません。

これまでの質問では、いくつの正規ファイルが存在しているかを尋ねただけです。これは、find . -type f | wc -lを実行することで簡単に把握できました。

バイナリ/アセンブリ以外の何かを意味していると仮定しているので、 "人間が読めるコンテンツ"が何であるかを判断するのが難しいですが、私はそれが-type fのものだと考えました。多分それは教授が "トリックの質問"と言った意味ですか?

この質問には、「どのテキストファイルに大文字と小文字を混在させた文字列「csc」が含まれていますか」という質問もあります。明らかに「テキスト」は単にファイル.txt以上を指していますが、これを決定する最初の質問を理解する必要があります。わかりやすくするために追加

+1

いいえ、 'find -type f'はディレクトリ、デバイスノードなどを除外します。 ( "spec ialファイル ")、すなわち純粋なファイル以外のファイルシステムオブジェクトである。ファイルの内容はまったく調べず、ディレクトリエントリ(inode)の型情報だけを調べます。 Unixは "バイナリ"と "テキスト"ファイルを区別していません(このUnixの頭には、そのような区別を定義しようとするどんな試みも滑りやすい斜面に入ります)。 – tripleee

答えて

6

引用:

ファイルはテキストファイルやバイナリデータファイルがあるかどうかを確認するために、ファイルの「ファイル」コマンドを実行します!

fileコマンドは、ファイルを検査し、どのようなファイルであるかを示します。 「テキスト」という単語は、テキストファイルの説明に(ほとんど)表示されます。例えば

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'やそのようなコマンドを実行しないと言っているように聞こえます。特定のファイル拡張子を想定しないでください。ファイル拡張子は、UNIXではWindowsでの意味よりもはるかに意味がありません。たくさんのファイルにはファイル拡張子がありません!


私は教授たちは、すべてのファイルに対してfileコマンドを実行し、その中に「テキスト」を持つものの数をカウントできるようにしたいと思っています。

複数のパートの回答はどうですか?おそらくあなたの教授が探しているものです#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に異なる結末を持っている場合、それは関係なく動作します

だからあなたはどうなるかなったような:

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!" 

と出力がかなったようなものだ:

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

人間が読めるより多くのMIMEタイプ(HTMLやXMLカウントなど)を見たい場合はhttp://www.feedforall.com/mime-types.htm

関連する問題