[gelöst] Wert aus Zeile lesen - ...
[gelöst] Wert aus Zeile lesen - ...
Hallo Forum,
bräuchte bitte einen geeigneten bash oder awk Befehl mittels dem ich das
Vorhaben beim * bekomme.
Komme damit irgendwie nicht zurecht. Meine, dies mittels awk zu ermitteln. Hab schon viel recherchiert,
bisher nicht herausgefunden wie ich einen Wert mit awk lesen kann, prüfe und ggfs. nur den nächsten Wert lese.
Da dies meine erste "grössere" script Aufgabe ist, sind jegliche Anregungen willkommen.
Auch, was den Ablauf betrifft.
Vielen Dank schon mal.
Pseudo
----------
- finde eine Anzahl Verzeichnisse (können beliebig viele sein)
- schreibe Verzeichnisgröße und Name in eine Datei mit einer bestimmten Reihenfolge. (1. Spalte = Größe, 2. Spalte = Name)
- lese den 1. Wert (1. Zeile, 1. Feld) aus Datei
- Vergleiche diesen Wert mit einer vorgegebenen Größe (maxsize)
- ist Wert < maxsize
ja
- ist Wert(Summe) + Wert aus nächster Zeile < maxsize *
ja (wiederhole und summiere bis nein)
nein
- besteht bereits eine datei.xxx (z.B. datei.001)
nein
- schreibe die Zeile(n), die annähernd die Größe von maxsize haben in eine neue Datei -> datei.001
- lösche die entsprechenden Zeilen aus original Datei
ja
- schreibe neue datei.xxx (xxx inkrementiert)
- lösche wiederum die zeilen
- wiederholen bis original Datei keine Zeilen enthält
bräuchte bitte einen geeigneten bash oder awk Befehl mittels dem ich das
Vorhaben beim * bekomme.
Komme damit irgendwie nicht zurecht. Meine, dies mittels awk zu ermitteln. Hab schon viel recherchiert,
bisher nicht herausgefunden wie ich einen Wert mit awk lesen kann, prüfe und ggfs. nur den nächsten Wert lese.
Da dies meine erste "grössere" script Aufgabe ist, sind jegliche Anregungen willkommen.
Auch, was den Ablauf betrifft.
Vielen Dank schon mal.
Pseudo
----------
- finde eine Anzahl Verzeichnisse (können beliebig viele sein)
- schreibe Verzeichnisgröße und Name in eine Datei mit einer bestimmten Reihenfolge. (1. Spalte = Größe, 2. Spalte = Name)
- lese den 1. Wert (1. Zeile, 1. Feld) aus Datei
- Vergleiche diesen Wert mit einer vorgegebenen Größe (maxsize)
- ist Wert < maxsize
ja
- ist Wert(Summe) + Wert aus nächster Zeile < maxsize *
ja (wiederhole und summiere bis nein)
nein
- besteht bereits eine datei.xxx (z.B. datei.001)
nein
- schreibe die Zeile(n), die annähernd die Größe von maxsize haben in eine neue Datei -> datei.001
- lösche die entsprechenden Zeilen aus original Datei
ja
- schreibe neue datei.xxx (xxx inkrementiert)
- lösche wiederum die zeilen
- wiederholen bis original Datei keine Zeilen enthält
Zuletzt geändert von ivato am 21.04.2006 17:56:36, insgesamt 1-mal geändert.
OK.
Danke für den Hinweis. Ziehe es in betracht.
Könnt Ihr mir eine grobe Einschätzung / Gegenüberstellung (Perl <--> Python) geben,
speziell zu meinem Problem?
Fange gerade auch an mich etwas in Python einzuarbeiten, oder würdet Ihr eher Perl empfehlen?
bash habe ich deshlab gewählt, da schon bischen mehr Erfahrung damit besteht.
Danke für den Hinweis. Ziehe es in betracht.
Könnt Ihr mir eine grobe Einschätzung / Gegenüberstellung (Perl <--> Python) geben,
speziell zu meinem Problem?
Fange gerade auch an mich etwas in Python einzuarbeiten, oder würdet Ihr eher Perl empfehlen?
bash habe ich deshlab gewählt, da schon bischen mehr Erfahrung damit besteht.
Schwierig... Insbesondere, da ich Python-Fan bin
Also was kurze Textmanipulationshacks angeht, ist perl nicht zu schlagen, dafür wurde es ja ursprünglich auch geschrieben.
Wenn du allgemein Programmieren lernen willst und/oder planst, größere Tools zu schreiben, würde ich dir zu Python raten.
Wenn du nur eine Sprache lernen willst, und:
1. Ab und an kleine Scripte wie dieses brauchst, und
2. Es dir nichts ausmacht, das du den Code u.U. in ein paar Wochen nicht mehr lesen kannst,
dann nimm Perl, sonst Python.
Wenn du Lust hast, beides zu lernen, würde ich dir empfehlen, dieses Skript in Perl zu schreiben. Ein bisschen Perl zu können ist nämlich nie verkehrt.
(Wenn dir die klare Syntax von Python nicht so sehr gefällt, und du Perls Kürze und "There's more than one way to do it"-Philosophie magst, solltest du dir auch mal Ruby anschauen)
Also was kurze Textmanipulationshacks angeht, ist perl nicht zu schlagen, dafür wurde es ja ursprünglich auch geschrieben.
Wenn du allgemein Programmieren lernen willst und/oder planst, größere Tools zu schreiben, würde ich dir zu Python raten.
Wenn du nur eine Sprache lernen willst, und:
1. Ab und an kleine Scripte wie dieses brauchst, und
2. Es dir nichts ausmacht, das du den Code u.U. in ein paar Wochen nicht mehr lesen kannst,
dann nimm Perl, sonst Python.
Wenn du Lust hast, beides zu lernen, würde ich dir empfehlen, dieses Skript in Perl zu schreiben. Ein bisschen Perl zu können ist nämlich nie verkehrt.
(Wenn dir die klare Syntax von Python nicht so sehr gefällt, und du Perls Kürze und "There's more than one way to do it"-Philosophie magst, solltest du dir auch mal Ruby anschauen)
ich habe mal ein bash Script nach deinen Vorgaben geschrieben. Aber besonders effizient oder schnell ist es nicht (zumal ich nicht gerade ein Meister der darin bin. ) Außerdem ist deine gewünschte Herangehensweise auch nicht gerade die beste. Das ständige öffnen und schließen der Dateien kostet eine Menge Zeit.
Das Script ist nicht lang, darum wage ich es, es mal direckt zu posten
Als Dreingabe habe ich das ganze nochmal in Perl geschrieben. Damit du sehen kannst wo die unterschiede sind. Es ist nur maginal kürzer.
Und so würde ich es in perl Schreiben (bash wäre äquivalent)
@Joghurt
Nunja ich finde Phyton unübersichtlich. Ich habe mich zwar schon mal damit beschäftigt, und mache Ansätze sind wirklich interessant, aber Perl gefällt mir einfach besser. (Und kann meinen Perlcode noch nach Jahren lesen.)
Das Script ist nicht lang, darum wage ich es, es mal direckt zu posten
Code: Alles auswählen
#!/bin/bash
# Dateiname für ZwischenAusgabe
TEMP_DAT="/TEMP/test_liste.txt"
# Dateinamen für Ausgabe
LISTE_DAT='datei.%03u'
# Liste von Verzeichnissen dirch Leerzeichen getrennt.
VERZEICHNISSE="/usr/bin/ /etc/ /var/log/";
# Gesammtgröße der Liste in Bite
GROESSE=100000
echo -n > $TEMP_DAT
for dir in $VERZEICHNISSE; do
echo $dir
liste=`ls -l $dir | awk '{printf "%u,%s\n",$5,$9}'`
IFS="
"
for line in $liste; do
lang=`expr length "$line"`
pos=`expr index "$line" ','`
let pos=pos-1
gross=`expr substr "$line" 1 $pos`
let pos=pos+2
name=`expr substr "$line" $pos $lang`
if [ $name != "" ]; then
echo "$gross,$dir$name" >> $TEMP_DAT
fi
done
IFS=" "
done
summe=0
cnt=0
IFS="
"
TEMP_DAT_NEU="$TEMP_DAT.neu"
echo $TEMP_DAT_NEU
while [ -s $TEMP_DAT ]; do
echo "C=$cnt"
cntb=0
echo -n > $TEMP_DAT_NEU
for line in `cat $TEMP_DAT`; do
if [ $cntb -eq 0 ]; then
cntb=1
lang=`expr index "$line" ','`
let lang=lang-1
gross=`expr substr "$line" 1 $lang`
let summe=summe+gross
if [ $summe -ge $GROESSE ]; then
summe=0
let cnt=cnt+1
name=`printf $LISTE_DAT $cnt`
echo $line > $name
else
name=`printf $LISTE_DAT $cnt`
echo $line >> $name
fi
else
echo $line >> $TEMP_DAT_NEU
fi
done
rm $TEMP_DAT
mv $TEMP_DAT_NEU $TEMP_DAT
done
Code: Alles auswählen
#!/usr/bin/perl
use strict;
# Dateiname für ZwischenAusgabe
my $TEMP_DAT='/TEMP/test_liste.txt';
# Dateinamen für Ausgabe
my $LISTE_DAT='datei.%03u';
# Liste von Verzeichnissen dirch Leerzeichen getrennt.
my @VERZEICHNISSE=qw|/usr/bin/ /etc/ /var/log/|;
# Gesammtgröße der Liste in Bite
my $GROESSE=100000;
open(TEMP ,'>',$TEMP_DAT) or die "konnte \"$TEMP_DAT\" nicht öffnen! ($!)\n";
for my $dir (@VERZEICHNISSE)
{
for my $name (<$dir*>)
{
my $gross=-s $name;
print TEMP "$gross,$name\n";
}
}
close(TEMP);
my $summe=0;
my $cnt=0;
while(-s $TEMP_DAT)
{
open(TEMP ,'+<',$TEMP_DAT) or die "konnte \"$TEMP_DAT\" nicht öffnen! ($!)\n";
my $line=<TEMP>;
chomp($line);
my ($gross, $name)=split(',',$line);
my $rest="";
while($_=<TEMP>)
{ $rest.=$_; }
seek(TEMP,0,0);
truncate(TEMP,0);
print TEMP $rest;
close(TEMP);
$summe+=$gross;
if($summe > $GROESSE)
{
$summe=0;
$cnt++;
my $out_name=sprintf($LISTE_DAT,$cnt);
open(OUT, '>', $out_name) or die "Konnte \"$out_name\" nicht öffen ($!)\n";
print OUT "$gross,$name\n";
close(OUT);
}
else
{
my $out_name=sprintf($LISTE_DAT,$cnt);
open(OUT, '>>', $out_name) or die "Konnte \"$out_name\" nicht öffen ($!)\n";
print OUT "$gross,$name\n";
close(OUT);
}
}
Code: Alles auswählen
#!/usr/bin/perl
use strict;
# Dateinamen für Ausgabe
my $LISTE_DAT='datei.%03u';
# Liste von Verzeichnissen dirch Leerzeichen getrennt.
my @VERZEICHNISSE=qw|/usr/bin/ /etc/ /var/log/|;
# Gesammtgröße der Liste in Bite
my $GROESSE=100000;
my $summe=0;
my $cnt=0;
my $out_name=sprintf($LISTE_DAT,$cnt);
open(OUT, '>', $out_name) or die "Konnte \"$out_name\" nicht öffnen ($!)\n";
for my $dir (@VERZEICHNISSE)
{
for my $name (<$dir*>)
{
my $gross=-s $name;
$summe+=$gross;
if($summe > $GROESSE)
{
$summe=0;
$cnt++;
close(OUT);
$out_name=sprintf($LISTE_DAT,$cnt);
open(OUT, '>', $out_name) or die "Konnte \"$out_name\" nicht öffnen ($!)\n";
}
print OUT "$gross,$name\n";
}
}
close(OUT);
Nunja ich finde Phyton unübersichtlich. Ich habe mich zwar schon mal damit beschäftigt, und mache Ansätze sind wirklich interessant, aber Perl gefällt mir einfach besser. (Und kann meinen Perlcode noch nach Jahren lesen.)