5

UNIX の入門コースを受講していて、次の宿題の質問があります。

前の質問で、テキスト ファイルはいくつのファイルですか? テキスト ファイルは、人間が判読できるコンテンツを含むファイルです。(トリックの質問。ファイルに対して file コマンドを実行して、そのファイルがテキスト ファイルかバイナリ データ ファイルかを確認してください。単に.txt拡張子の付いたファイルの数を数えると、この質問のポイントは得られません。)

前の質問では、通常のファイルがいくつあるかを尋ねただけで、実行することで簡単に把握できましたfind . -type f | wc -l

「人間が読めるコンテンツ」とは何かを判断するのに苦労しています。これは、バイナリ/アセンブリ以外の何かを意味すると想定しているためですが、それが表示されると思いました-type f。ひょっとして、教授が「ひっかけ問題」と言ったのは、そういう意味だったのでしょうか。

この質問には、「大文字と小文字が混在する文字列「csc」を含むテキスト ファイルはどれですか?」というフォローアップがあります。明らかに「テキスト」は単なるファイル以上のものを指してい.txtますが、これを判断するには最初の質問を理解する必要があります!

4

2 に答える 2

6

明確にするために追加された引用:

ファイルに対して「file」コマンドを実行して、ファイルがテキスト ファイルかバイナリ データ ファイルかを確認してください。

この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その出力を解析するよう求めています。

「人間が読めるコンテンツ」とは何かを判断するのに苦労しています。これは、バイナリ/アセンブリ以外の何かを意味すると想定しているためですが、-type f が表示するものだと思いました。

find -type fファイルを検索します。ディレクトリ、シンボリック リンク、ソケットなどの他のファイル システム オブジェクトを除外します。ただし、バイナリ ファイル、テキスト ファイルなど、あらゆる種類のファイルに一致します。

ひょっとして、教授が「ひっかけ問題」と言ったのは、そういう意味だったのでしょうか。

find -name '*.txt'彼は、テキストファイルを検索するためのコマンドを実行しない、またはそのようなコマンドを言っているだけのようです。特定のファイル拡張子を想定しないでください。ファイル拡張子は、Windows よりも UNIX ではあまり意味がありません。多くのファイルにはファイル拡張子さえありません!


教授は、すべてのファイルに対して file コマンドを実行し、「テキスト」を含むファイルの数を数えられるようにしてほしいと考えています。

マルチパートの答えはどうですか?#1で簡単な解決策を示します。これはおそらくあなたの教授が探しているものです. 興味があれば、その欠点とそれを改善する方法を説明します。

  1. 1 つの方法はxargs、それについて学んだ場合は、 を使用することです。xargsstdin からのデータをそのコマンドの引数として使用して、別のコマンドを実行します。

    $ 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

于 2012-09-29T15:34:47.560 に答える
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を参照してください。

于 2012-10-01T06:38:55.863 に答える