Schlagwort-Archive: Datei

Eine Datei umbenennen und dabei das Datum anfügen

Des öfteren kommt man die die Verlegenheit, dass man eine Datei so umbenennen möchte, dass das Modifikationsdatum der Datei an den Namen angehängt wird. Zum Beispiel soll aus „foo.bar“ die Datei „foo.bar_2013-02-12“ werden.

Jetzt kann man das natürlich so von Hand tippen, nach dem man sich mit ls -l über das entsprechende Datum informiert hat. Man kann das aber auch die Shell machen lassen:

mv foo.bar foo.bar_`stat -c '%y' foo.bar | cut -f 1 -d " "`

Dabei muss man aber viel tippen und vor allem den Dateinamen gleich drei mal. Das geht auch anders:

THEFILE=foo.bar && mv $THEFILE ${THEFILE}_`stat -c '%y' $THEFILE | cut -f 1 -d " "`

Weiterhin viel Tipparbeit, daher bauen wir daraus am besten einen Alias. Allerdings kann man einem Alias keine Parameter übergeben, daher machen wir eine Funktion daraus und tragen das folgende in unsere bash.rc ein:

mvdate(){ mv $1 ${1}_`stat -c '%y' $1 | cut -f 1 -d " "`; }

Nun macht mvdate foo.bar aus der Datei „foo.bar“ die „foo.bar_2013-02-12“.

 

Perl: Einen Hash aus einer Datei befüllen

Manchmal muss man eine Liste aus einer Datei einlesen, weil man nach Elementen aus dieser Liste suchen möchte. Hier bietet es sich an, die Daten in einen Hash einzulesen. Und das geht erfreulich einfach mit:

open LIST, '<', $nodefile or die "Cannot open '$nodefile' $!";
my %nodelist = map /^([^;]+)\s*;\s*(.+)\s*$/, <LIST>;
close LIST;

Man öffnet die Datei zum Lesen und map macht den Rest. In der Datei sind die Werte durch ein Semikolon getrennt (CSV-Datei). Hat man ein Gleichheitszeichen als Trenner, dann sieht die Zeile so aus:

my %nodelist = map /^([^=]+)\s*=\s*(.+)\s*$/, <LIST>;

Hier das Ganze als komplettes Perl-Skript:

#!/usr/bin/perl
use warnings;
use strict;
use Getopt::Std;

my $nodefile;
my %option;
my $usage = "USAGE: $0 -N filename\n";

unless(getopts("N:", \%option)) {
 die "$usage";
}
if(defined $option{N}) {
 $nodefile = $option{N};
} else {
 die "$usage";
}

open LIST, '<', $nodefile or die "Cannot open '$nodefile' $!";

my %nodelist = map /^([^;]+)\s*;\s*(.+)\s*$/, <LIST>;

close LIST;

for my $entry ( sort keys %nodelist ) {
 print "$entry: $nodelist{$entry}\n";
}

Dateien mit Sym- oder Hardlinks finden

Symlinks finden

Das Verlinken von Dateien oder Verzeichnissen per Symlink ist eine prima Sache. Schwierig wird es nur, wenn man Dateien löscht oder verschiebt, auf die Symlinks zeigen. Diese laufen dann nämlich ins Leere. Um zu prüfen, ob es Symlinks auf eine Datei oder ein Verzeichnis gibt, nutz man das folgende Kommando:

find / -type l -print | xargs ls -ld | grep 'dateiname'

Das kann ich auch verwenden, wenn ich z.B. ein Verzeichnis verschieben will und nicht weiß, ob es Links auf Dateien oder Unterverzeichnisse im fraglichen Verzeichnis gibt. Ich setze dann als ‚dateiname‘ den Namen des Verzeichnisses ein, das ich verschieben will.

Siehe auch http://www.grymoire.com/Unix/Find.html#uh-6

Hardlinks finden

Mitunter benutzt man auch Hardlinks, um Dateien zu verlinken (z.B. Backup mit rsync, wie in der c’t 07/2009, S. 212 beschrieben). Hat man nun eine Datei, bei der man anhand des Linkcount erkennt, dass sie Hardlinks hat, will man evt. auch wissen, wo die anderen Links liegen. Mit

find . ! -type d -links +1 -ls|sort -n

findet man alle Dateien, deren Linkcount größer 1 ist. Durch die Sortierung anhand des Inodes (erste Spalte) kann man gut zusammengehörende Dateien erkennen.

Will man für eine Bestimmte Datei die zugehörigen Links finden, geht das auch so:

f=`ls -i dateiname |awk '{print $1}'`
find / -inum $f

Siehe auch: The UNIX and Linux Forums: search for hardlinks based on filename via find command.

Dateien finden, die nicht von allen gelesen werden können

Manchmal muss man die Dateien finden, deren Rechte so gesetzt sind, dass sie nicht von allen gelesen werden können. Mit

find . -type f -not -perm -0004 -ls

findet man alle Dateien im aktuellen Verzeichnis und darunter, deren Worldreadable-Bit nicht gesetzt ist.

Und so macht man sie für alle lesbar:

find . -type f -not -perm -0004 -exec chmod -c a+r {} ;

Das gleiche für Verzeichnisse:

find . -type d -not -perm -0004 -exec chmod -c a+rx {} ;