Du bist nicht angemeldet.
Hallo,
ich möchte eine Statistik über alle Dateien in einem Verzeichnis inkl. Unterverzeichnisse erstellen.
Diese Statistik soll folgende Daten enthalten:
Creation Time
Size
Path
Directory
Bisher habe ich diesen Befehl verwendet:
find /mnt/rbd -type f -printf "%P,%AY-%Am-%Ad,%TY-%Tm-%Td,%s\n" | sed 's/\(.*\)\//\1,/'
Die Ausgabe wäre dann so:
ld2896/GWR/translocal/tmp,SAPRUPGM.GWR,2019-10-20,2017-09-29,956
ld2896/GWR/translocal/tmp,UMODPROT.GWR,2019-10-20,2017-09-29,2019
ld2896/GWR/translocal,transdir.template.tar,2019-10-20,2017-09-29,10240
Für meine Anforderung wäre es besser, die Ausgabe sähe so aus:
ld2896/GWR/translocal/tmp/SAPRUPGM.GWR,ld2896/GWR,2019-10-20,2017-09-29,956
ld2896/GWR/translocal/tmp/UMODPROT.GWR,ld2896/GWR,2019-10-20,2017-09-29,2019
Mit welchem sed Syntax lässt sich dies erzielen?
THX
Beitrag geändert von cmonty14 (23.10.2019 16:37:48)
Offline
Wie berechnest du das zweite Feld "ld2896/GWR"? Was wird dort angezeigt bei Dateien welche direkt in ld2896 liegen?
Offline
Das 2. Feld lässt sich durch eine zusätzliche Option von printf %P berechnen.
Vermutlich wäre es einfacher, das Ergebnis in diese Spalten zu unterteilen:
DIR,PATH,ACCESS_TIME,CREATION_TIME,SIZE
find /mnt/rbd -type f -printf "%P,%P,%AY-%Am-%Ad,%TY-%Tm-%Td,%s\n"
Die Frage ist dann, wie der Syntax von sed aussehen muss?
Offline
Deswegen frage ich dich, was im Fall der Datei "ld2896/foobar.txt" dort stehen soll.
Offline
In diesem Fall soll dort stehen: ld2896
Also ohne die Angabe des Dateinamens.
Beitrag geändert von cmonty14 (22.10.2019 15:30:13)
Offline
Also sollen in diesem Feld der jeweils erste und falls möglich noch der zweite Ordner, jedoch keine weiteren Ordner des Verzeichnispfades angezeigt werden?
Was soll bei einer Datei passieren, welche nicht in "ld2896" sondern direkt in "/mnt/rbd" liegt?
Offline
Also sollen in diesem Feld der jeweils erste und falls möglich noch der zweite Ordner, jedoch keine weiteren Ordner des Verzeichnispfades angezeigt werden?
Das ist absolut richtig.
Was soll bei einer Datei passieren, welche nicht in "ld2896" sondern direkt in "/mnt/rbd" liegt?
Das ist nicht der Fall, es gibt keine Dateien direkt in /mnt/rbd.
Beitrag geändert von cmonty14 (22.10.2019 15:49:54)
Offline
Ich würde bei so einer komplexen Formatierung dann direkt zu einer Skriptsprache greifen.
Besonders, weil ich selbst kein sed Guru bin, und den Code wahrscheinlich nicht auf Anhieb verstehen könnte.
Dieses Skript sollte deine gewünschte Ausgabe erzeugen:
#! /usr/bin/env python3
"""Lists stats of files as CSV records as per
https://bbs.archlinux.de/viewtopic.php?id=32798
"""
from contextlib import suppress
from datetime import datetime
from pathlib import Path
def list_files(basedir):
"""Yields file paths within the base dir."""
for inode in basedir.rglob('*'):
if inode.is_file():
yield inode
def file_stats(path):
"""Returns file stats of the respective path in the desired format."""
stats = path.stat()
mtime = datetime.fromtimestamp(stats.st_mtime).date().isoformat()
ctime = datetime.fromtimestamp(stats.st_ctime).date().isoformat()
size = stats.st_size
parents = tuple(path.parents)
try:
basedir = parents[-3]
except IndexError:
basedir = parents[-2]
return f'{path},{basedir},{mtime},{ctime},{size}'
def main():
"""Runs the script."""
basedir = Path.cwd()
for file in list_files(basedir):
with suppress(IndexError):
print(file_stats(file))
if __name__ == '__main__':
main()
Offline
THX
Dein Script funktioniert leide nicht zu 100% so wie erwartet.
Die Ausgabe sieht so aus:
root@ld3955:/mnt/rbd# /home/file_stats.py | tail
/mnt/rbd/ld4243/LOG/log.863,/mnt/rbd,2017-04-27,2019-10-18,786432
/mnt/rbd/ld4243/LOG/log.864,/mnt/rbd,2017-04-27,2019-10-18,1703936
/mnt/rbd/ld4243/LOG/log.865,/mnt/rbd,2017-04-27,2019-10-18,851968
/mnt/rbd/ld4243/LOG/log.866,/mnt/rbd,2017-04-27,2019-10-18,983040
/mnt/rbd/ld4243/LOG/log.867,/mnt/rbd,2017-04-27,2019-10-18,786432
/mnt/rbd/ld4243/LOG/log.868,/mnt/rbd,2017-04-27,2019-10-18,786432
/mnt/rbd/ld4653/ML1/ML1_19092019_databackup_0_1,/mnt/rbd,2019-09-19,2019-10-18,155648
/mnt/rbd/ld4653/ML1/ML1_19092019_databackup_2_1,/mnt/rbd,2019-09-19,2019-10-18,1118788657152
/mnt/rbd/ld4653/ML1/ML1_19092019_databackup_3_1,/mnt/rbd,2019-09-19,2019-10-18,83894272
/mnt/rbd/ld4653/ML1/ML1_19092019_databackup_4_1,/mnt/rbd,2019-09-19,2019-10-18,100671488
Das heißt, die Angabe des Verzeichnisses in Spalte 2 enthält eine Unterverzeichnis-Ebene zu wenig.
Beitrag geändert von cmonty14 (23.10.2019 07:51:28)
Offline
Ups, ja ich habe übersehen, dass du nur die relativen Unterordner benötigst:
#! /usr/bin/env python3
"""Lists stats of files as CSV records as per
https://bbs.archlinux.de/viewtopic.php?id=32798
"""
from contextlib import suppress
from datetime import datetime
from pathlib import Path
from sys import argv
def list_files(basedir):
"""Yields file paths within the base dir."""
for inode in basedir.rglob('*'):
if inode.is_file():
yield inode
def file_stats(path, basedir):
"""Returns file stats of the respective path in the desired format."""
stats = path.stat()
mtime = datetime.fromtimestamp(stats.st_mtime).date().isoformat()
ctime = datetime.fromtimestamp(stats.st_ctime).date().isoformat()
size = stats.st_size
path = path.relative_to(basedir)
parents = tuple(path.parents)
try:
basedir = parents[-3]
except IndexError:
basedir = parents[-2]
return f'{path},{basedir},{mtime},{ctime},{size}'
def main():
"""Runs the script."""
try:
basedir = Path(argv[1])
except IndexError:
basedir = Path.cwd()
for file in list_files(basedir):
with suppress(IndexError):
print(file_stats(file, basedir))
if __name__ == '__main__':
main()
Um den aktuellen Ordner aufzulisten:
./script.py
Um einen spezifischen Ordner aufzulisten:
./script.py /pfad/zum/ordner
Offline
Vielen Dank für die Modifikation.
Ich habe, auf Basis des vorigen Scripts, bereits mit der Auswertung begonnen (MS Excel) und festgestellt, dass ich noch eine weitere Spalte benötige.
Das heißt, der gewünschte Output sollte so aussehen:
Path,Subdir;Dir,Mtime,Ctime,Size
ld4243/LOG/log.863,ld4243/LOG,ld4243,2017-04-27,2019-10-18,786432
ld4243/LOG/log.864,ld4243/LOG,ld4243,2017-04-27,2019-10-18,1703936
ld4243/LOG/log.865,ld4243/LOG,ld4243,2017-04-27,2019-10-18,851968
ld4243/LOG/log.866,ld4243/LOG,ld4243,2017-04-27,2019-10-18,983040
ld4243/LOG/log.867,ld4243/LOG,ld4243,2017-04-27,2019-10-18,786432
ld4243/LOG/log.868,ld4243/LOG,ld4243,2017-04-27,2019-10-18,786432
ld4653/ML1/ML1_19092019_databackup_0_1,ld4653/ML1,ld4243,2019-09-19,2019-10-18,155648
ld4653/ML1/ML1_19092019_databackup_2_1,ld4653/ML1,ld4243,2019-09-19,2019-10-18,1118788657152
ld4653/ML1/ML1_19092019_databackup_3_1,ld4653/ML1,ld4243,2019-09-19,2019-10-18,83894272
ld4653/ML1/ML1_19092019_databackup_4_1,ld4653/ML1,ld4243,2019-09-19,2019-10-18,100671488
Welche Änderung ist notwendig, um die zusätzliche Spalte Dir zu erstellen?
Offline
Diese hier
--- lsfilestats.py 2019-10-23 14:10:07.139856126 +0200
+++ lsfilestats2.py 2019-10-23 14:11:05.060301620 +0200
@@ -26,13 +26,14 @@
size = stats.st_size
path = path.relative_to(basedir)
parents = tuple(path.parents)
+ basedir1 = parents[-2]
try:
- basedir = parents[-3]
+ basedir2 = parents[-3]
except IndexError:
- basedir = parents[-2]
+ basedir2 = basedir1
- return f'{path},{basedir},{mtime},{ctime},{size}'
+ return f'{path},{basedir2},{basedir1},{mtime},{ctime},{size}'
def main():
Dies gibt in der zweiten Spalte die ersten beiden oder den ersten Unterordner aus und in der dritten Spalte den ersten Unterordner.
Offline
Wonderbra!
Die Ausgabe ist nach dieser Modifikation wie gewünscht.
Vielen, vielen Dank!
Offline