2012-09-29 10 views
5

Ich bin ein Intro Kurs UNIX zu nehmen und eine Hausaufgaben Frage haben, der folgt:Wie alle lesbaren Dateien in Bash zu zählen?

Dateien

Wie viele Dateien in der vorherigen Frage sind Text? Eine Textdatei ist eine Datei, die lesbaren Inhalt enthält. (TRICK FRAGE. Führen Sie den Dateibefehl für eine Datei, um zu sehen, ob die Datei eine Textdatei oder eine binäre Datei ist! Wenn Sie einfach die Anzahl der Dateien mit der Erweiterung .txt zählen, erhalten Sie keine Punkte für diese Frage.)

Bei der vorherigen Frage wurde einfach gefragt, wie viele reguläre Dateien es gab, was man leicht herausfinden konnte, indem man find . -type f | wc -l tat.

Ich habe nur Probleme zu bestimmen, was "lesbarer Inhalt" ist, da ich nehme an, es bedeutet alles außer Binär/Assembly, aber ich dachte, das ist, was -type f angezeigt wird. Vielleicht meinte der Professor das mit "Trickfrage"?

Diese Frage hat später eine Folge, die auch fragt: "Welche Textdateien enthalten die Zeichenfolge" csc "in einer Mischung aus Groß- und Kleinschreibung?". Offensichtlich bezieht sich "Text" auf mehr als nur .txt Dateien, aber ich muss die erste Frage herausfinden, um das zu bestimmen!

+1

Nein, 'finden -Typ f' schließt Verzeichnisse, Geräteknoten usw. ("spec Dateien "), d. h. Dateisystem-Objekte, die keine reinen Dateien sind. Es untersucht nicht den Inhalt von Dateien überhaupt, nur die Typinformationen im Verzeichniseintrag (Inode). Unix unterscheidet nicht zwischen "binären" und "Text" -Dateien (und bei diesem Unix-Kopf tritt jeder Versuch, eine solche Unterscheidung zu definieren, in einen schlüpfrigen Abhang). – tripleee

Antwort

6

hinzugefügt Zitate für Klarheit:

Führen Sie den Befehl „file“ auf eine Datei, um zu sehen, ob die Datei eine Textdatei oder eine binäre Datendatei!

Der Befehl file prüft Dateien und sagt Ihnen, welche Art von Datei sie zu sein scheinen. Das Wort "Text" wird (fast) immer in der Beschreibung für Textdateien stehen.

Zum Beispiel:

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

So ist der erste Teil, das Sie bittet den file Befehl ausführen und seine Ausgabe zu analysieren.

Ich habe nur Probleme zu bestimmen, was "lesbarer Inhalt" ist, da ich annehme, dass es alles außer binär/Assembly bedeutet, aber ich dachte, dass das was Typ f anzeigt.

find -type f findet Dateien. Es filtert andere Dateisystemobjekte wie Verzeichnisse, Symlinks und Sockets aus. Es passt jedoch zu jeder Art von Datei: Binärdateien, Textdateien, alles.

Vielleicht meinte der Professor das mit "Trickfrage"?

Es klingt wie er gerade sagt nicht tun find -name '*.txt' oder einige solcher Befehl Textdateien zu finden. Gehen Sie nicht von einer bestimmten Dateierweiterung aus. Dateierweiterungen haben unter UNIX eine wesentlich geringere Bedeutung als unter Windows. Viele Dateien haben nicht einmal Dateiendungen!


ich den Professor denke will uns in der Lage sein, den Datei-Befehl für alle Dateien ausgeführt werden und die Anzahl von Einsen mit ‚Text‘ in ihm zählen.

Wie wäre es mit einer mehrteiligen Antwort? Ich werde die einfache Lösung in # 1 geben, was wahrscheinlich Ihr Professor ist. Und wenn Sie interessiert sind, erkläre ich seine Mängel und wie Sie es verbessern können.

  1. Eine Möglichkeit ist xargs zu verwenden, wenn Sie das gelernt haben. xargs führt einen anderen Befehl aus, wobei die Daten von stdin als Argumente dieses Befehls verwendet werden.

    $ 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. Das funktioniert. Irgendwie. Es wäre gut genug für eine Hausaufgabe. Aber nicht gut genug für eine echte Weltschrift.

    Beachten Sie, wie es auf die Datei VMWare (copy).desktop brach, weil es einen Platz darin hat. Dies liegt an xargs Standardverhalten der Aufteilung der Argumente auf Leerzeichen. Wir können das beheben, indem wir xargs -0 verwenden, um Befehlsargumente auf NUL-Zeichen anstelle von Leerzeichen zu teilen. Dateinamen können keine NUL-Zeichen enthalten, so dass sie alles verarbeiten können.

    $ 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. Das ist gut genug für eine Produktions Skript, und ist etwas, das Sie viel begegnen werden. Aber ich persönlich bevorzuge eine alternative Syntax, die keine Pipe benötigt und daher etwas effizienter ist.

    $ 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 
    

    Um das zu verstehen, -exec ruft file wiederholt, es findet {} mit jedem Dateinamen zu ersetzen. Das Semikolon \; markiert das Ende des Befehls file.

+0

Sicherlich "menschlich lesbar" ist eine Funktion des Menschen und nicht der Datei. Ich hatte immer den starken Eindruck, dass die meisten Dateien mit dem Namen README von den meisten Menschen nicht lesbar sind. – rici

+0

Danke für die Hilfe Jungs, ich weiß, dass Datei kann bestimmen, ob eine Datei eine 'Text' Datei ist, aber ich habe vergessen zu erwähnen, dass das Endergebnis der ersten Frage in Bezug auf die Suche nach regulären Dateien in 153 Dateien (es ist ein Verzeichnis Ich denke, der Professor möchte, dass wir den Dateibefehl für alle Dateien ausführen und die Anzahl der Einsen mit "Text" zählen können.Wie würde ich das tun, vorausgesetzt, es ist möglich? – Rekson

+0

@ user1687406 Meine Antwort wurde mit einer (sehr) detaillierten Erklärung zur Kombination von 'find' und' file' aktualisiert. Ich habe mich nicht damit beschäftigt, die Ausgabe zu "grepen". Lassen Sie es mich wissen, wenn Sie Hilfe dabei haben möchten. –

0

ist es eine schöne und einfache Möglichkeit, um festzustellen, ob eine Datei eine vom Menschen lesbare Textdatei ist, verwenden Sie einfach file --mime-type <filename> und sucht nach 'text/plain'. Es wird funktionieren, egal, ob die Datei ein Ende hat oder ein anderes Ende hat .txt

Also würde man etw tun:

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

und der Ausgang etw gefallen würde:

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

Wenn Sie es weiter, um mehr Mime-Typen zu übernehmen wollen, die Menschen lesbar sind (zB nicht HTML und/oder XML zählen?) haben einen Blick auf http://www.feedforall.com/mime-types.htm

Verwandte Themen