Inkonsistente Ergebnisse bei der Ausgabe von ls

1

Ich habe Schwierigkeiten zu verstehen, warum ich unterschiedliche Ausgaben bekomme, wenn derselbe Befehl in einer einzigen Datei in Terminal (Mac OS X 10.6.8) ausgeführt wird und auf mehr als einer Datei ausgeführt wird. Da ich den Befehl in einem Bash-Skript ausführen möchte, versuche ich, konsistente Ergebnisse zu erzielen, wenn jeweils nur eine Datei ausgeführt wird.

Der Befehl gibt mir das Problem

ls -l "filename" | cut -f8 -d' '

Ich versuche, die Dateigröße zu isolieren.

Es scheint, dass dies für Dateien ohne erweiterte Berechtigungen funktioniert (z. B. ein erstes Feld von "-rw-r - r--"), aber für diejenigen mit erweiterten Berechtigungen (z. B. ein erstes Feld von "-rwxrwxrwx @") brauche ich cut -f7 -d ''

Interessanterweise, wenn ich eine Datei von jedem Typ auswähle und ausführen:

ls -l "filename1" "filename2" | cut -f8 -d' '

Es gibt die Dateigröße für zurück beide Dateien ohne Problem. Ich verstehe nicht, warum das passieren sollte ... aber natürlich mache ich in meinem Skript diese eine Datei zu einer Zeit.

Ich habe versucht, mit sed doppelte Leerzeichen und doppelte Tabulatoren zu entfernen. Dadurch ändert sich die erforderliche Feldnummer, um die Dateigröße anzugeben. Es scheint jedoch immer noch Ergebnisse zu geben, die davon abhängen, ob sie erweiterte Dateiberechtigungen haben oder nicht.

Ich füge die while-Schleife aus meinem Skript als Referenz ein, aber sie kann nicht leicht gelesen werden, da die Dateigröße nur eines der vier durch Doppelpunkte getrennten Felder ist, die ich einfügte.

#!/bin/bash

# lots of other stuff here including specifying input (which is a list of filenames with complete paths) and output files  ...

while IFS= read -r line
do
    echo "$line":`exiftool -all= -o - "$line" | md5`:`md5 "$line" | cut -f2 -d'=' | sed -e 's/^[ \t]*//'`:`ls -l "$line" | cut -f8 -d' '` >> "$outputfile"
done < "$file"

Kann mir jemand helfen, etwas Licht auf mich zu werfen?

yvf5rcuya4
quelle

Antworten:

1

Das eigentliche Problem ist, dass Sie es versuchen parse die Ausgabe von ls. Das ist noch nie eine gute Idee, und wie Sie festgestellt haben, kann es leicht brechen. Ausnahmsweise ist es nicht einmal auf Betriebssysteme portierbar. Parsing ls ist oft ein Symptom dafür, dass Sie etwas anderes tun müssen, als etwas dagegen tun (und das ist XY-Problem ).

Wie auch immer, du fragst:

Ich versuche, die Dateigröße zu isolieren.

Dann nutzen Sie einfach wc -c:

wc -c < filename

Dadurch erhalten Sie die Dateigröße in Byte (im Gegensatz zu du was gibt Ihnen Blöcke). Sie können den Whitespace trimmen, indem Sie in das Pipeing-Modul springen tr -d ' ' oder ähnliches.

Als kleiner Tipp für Ihre Schleife: Anstatt Backticks zum Ersetzen von Befehlen zu verwenden, tun Sie sich selbst einen Gefallen und verwenden Sie sie $(), z.B. $(md5 "$line" | cut -f2 -d'=' | sed -e 's/^[ \t]*//'). Dies hat verschiedene Vorteile, einschließlich verbesserter Lesbarkeit und weniger Kopfschmerzen beim Schachteln solcher Befehle.

slhck
quelle
1
Vielen Dank. Dies war wirklich der Fall, dass ich das Holz nicht für die Bäume sehen konnte, da ich mich zu sehr darauf konzentrierte, warum es nicht funktionierte und nicht, wie man es zum Laufen brachte.
yvf5rcuya4