ubuntuusers.de

stat: Datum formatieren

Status: Gelöst | Ubuntu-Version: Kubuntu 18.04 (Bionic Beaver)
Antworten |

michahe

Anmeldungsdatum:
12. Dezember 2013

Beiträge: 857

Hallo,

stat liefert mir die Zeitstempel atime, mtime und ctime von Dateien

$stat -c "File: %n||atime: %x||mtime: %y||ctime: %z" * 
#gekürzt in
$stat -c '%y' *
2016-10-20 19:54:20.000000000 +0200
2016-10-23 16:50:01.000000000 +0200
2016-10-23 16:50:03.000000000 +0200

Ich möchte nur die Zeitstempel in der Form "DD.MM.YYYY hh:mm:ss". Für eine einzelne Datei klappt das "fast richtig" mit date

$date -d "@$( stat -c '%Y' *Hey* )" +'%F %T'
2016-10-23 16:50:01

Wie muss der Befehl lauten, um Zeitstempel für mehrere Dateien so (und möglichst auch DD.MM.YYYY) zu formatieren?

Danke, Michael

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

Man könnte z.B. sowas machen:

1
stat -c '%y' *| cut -d ' ' -f 1-2 | sed 's/\.[0-9]*$//;s/-/./g'

Oder mit Python3:

1
2
3
4
5
6
#!/usr/bin/env python3
import datetime
from pathlib import Path

for file in Path('.').glob('*'):
    print(datetime.datetime.fromtimestamp(file.stat().st_mtime).strftime("%d.%m.%Y %H:%M:%S"))

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13209

michahe schrieb:

$date -d "@$( stat -c '%Y' *Hey* )" +'%F %T'
2016-10-23 16:50:01

Wie muss der Befehl lauten, um Zeitstempel für mehrere Dateien so (und möglichst auch DD.MM.YYYY) zu formatieren?

Die einfachste Variante wäre eine Schleife:

1
2
3
for f in *Hey*; do
  date -d "@$( stat -c '%Y' "$f" )" '+%F %T'
done

michahe

(Themenstarter)

Anmeldungsdatum:
12. Dezember 2013

Beiträge: 857

Vielen Dank für die Vorschläge, ich habe die Variante von rklm mit der Schleife probiert, für das mdate klappt das einwandfrei:

1
2
3
for f in *; do
   date -d "@$( stat -c '%Y' "$f" )" '+%F %T'
done

Trotzdem scheitere ich an der Syntax für die zusammengesetzte stat-Zeile:

$stat -c "File: %n||atime: %x||mtime: %y||ctime: %z" * 

Ich möchte je Datei eine Zeile, Dateinamen und mit den drei Zeitstempeln, alle drei formatiert DD.MM.YYYY HH:MM:SS.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11261

Wohnort: München

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python3
import datetime
import sys
from pathlib import Path


def get_time(ts: int) -> str:
    return datetime.datetime.fromtimestamp(ts).strftime("%d.%m.%Y %H:%M:%S")


for path in sys.argv[1:] if sys.argv[1:] else ["."]:
    for p in Path(path).glob("*"):
        if not p.is_file():
            continue
        st = p.stat()
        print(
            "||".join(
                (
                    f"File: {p}",
                    f"atime: {get_time(st.st_atime)}",
                    f"mtime: {get_time(st.st_mtime)}",
                    f"ctime: {get_time(st.st_ctime)}",
                )
            )
        )
$ ./print_stat.py /tmp
File: /tmp/.X1025-lock||atime: 12.06.2020 08:52:43||mtime: 12.06.2020 08:52:43||ctime: 12.06.2020 08:52:43
File: /tmp/config-err-Jg1Y2T||atime: 12.06.2020 08:52:59||mtime: 12.06.2020 08:52:59||ctime: 12.06.2020 08:52:59
File: /tmp/print_stat.py||atime: 12.06.2020 20:15:19||mtime: 12.06.2020 20:14:07||ctime: 12.06.2020 20:15:17
File: /tmp/.X1024-lock||atime: 12.06.2020 08:52:43||mtime: 12.06.2020 08:52:43||ctime: 12.06.2020 08:52:43 

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13209

michahe schrieb:

Trotzdem scheitere ich an der Syntax für die zusammengesetzte stat-Zeile:

$stat -c "File: %n||atime: %x||mtime: %y||ctime: %z" * 

Ich möchte je Datei eine Zeile, Dateinamen und mit den drei Zeitstempeln, alle drei formatiert DD.MM.YYYY HH:MM:SS.

Leicht:

1
2
3
4
5
d() { date -d "@$1" '+%F %T'; }

for f in *; do
   echo "File: $f||atime: $(d $(stat -c %X "$f"))||mtime: $(d $(stat -c %Y "$f"))||ctime: $(d $(stat -c %Z "$f"))"
done

oder mit noch weniger Redundanz

1
2
3
4
5
d() { date -d "@$(stat -c "$1" "$2")" '+%F %T'; }

for f in *; do
   echo "File: $f||atime: $(d %X "$f")||mtime: $(d %Y "$f")||ctime: $(d %Z "$f")"
done

mit weniger stat-Aufrufen in der bash

1
2
3
4
5
6
d() { date -d "@$1" '+%F %T'; }

for f in *; do
   times=( $(stat -c '%X %Y %Z' "$f") )
   echo "File: $f||atime: $(d ${times[0]})||mtime: $(d ${times[1]})||ctime: $(d ${times[2]})"
done

michahe

(Themenstarter)

Anmeldungsdatum:
12. Dezember 2013

Beiträge: 857

Ein riesiges Dankeschön an rklm und seahawk1986,

Ihr seid großartig, funktioniert perfekt! Wenn ich so etwas doch nur auch alleine schaffen würde ...

Gruß und ein sonniges Wochenende, Michael

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13209

Weil ich gerade Lust habe, hier noch eine Ruby-Lösung:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/ruby

require 'pathname'

class Time
  def fmt
    strftime '%F %T'
  end
end

ARGV.each do |f|
  f = Pathname(f)
  puts "File: #{f}||atime: #{f.atime.fmt}||mtime: #{f.mtime.fmt}||ctime: #{f.ctime.fmt}"
end

Eine der netten Eigenschaften von Ruby ist die Möglichkeit, Methoden zu bestehenden Klassen, Modulen und sogar Instanzen hinzufügen zu können. Das habe ich hier genutzt, um der Klasse Time die Methode #fmt hinzuzufügen, die das gewünschte Format erzeugt.

Antworten |