------------------------------------------------------------
-
- Beiträge: 174
- Registriert: 29.04.2012 22:55:06
------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:48:44, insgesamt 2-mal geändert.
Re: awk und noch was
(Ein Testverzeichnis mit einigen Ordnern */desktop/ddd4/ und Dateien)Meine Ausgabe am Terminal bleibt leer.
Code: Alles auswählen
$ ./test.dfde.bash
bash: ./test.dfde.bash: bin/bash: Defekter Interpreter: Datei oder Verzeichnis nicht gefunden
Code: Alles auswählen
$ ./test.dfde.bash
sha256sum: ungültige Option -- „y“
„sha256sum --help“ gibt weitere Informationen.
./test.dfde.bash: Zeile 13: Syntaxfehler beim unerwarteten Wort `echo'
./test.dfde.bash: Zeile 13: ` for $((proof+1)) echo "ZAEHLER" $proof'
Code: Alles auswählen
$ ./test.dfde.bash
sha256sum: ungültige Option -- „y“
„sha256sum --help“ gibt weitere Informationen.
./test.dfde.bash: Zeile 8: [: Zu viele Argumente.
was soll das machen?proof=$(sha256sum file -type f -name)
...
sha256sum file -type f | ....
'sha256sum' hat keine Optionen '-type' oder '-name', zumindest nicht in wheezy.
Ich kenne ein 'find [verz/] -type f -name ........'.
Soll das vielleicht ein zsh-Skript sein,
welche (mystifizierend) bei Auftreten von solchen Optionen wie '-type f' automatisch das passende Programm 'find' impliziert?
Oder ist da so ein bashism drin?
Ist 'sha256sum' vielleicht eine vorher definierte Funktion?
Code: Alles auswählen
$ which sha256sum
/usr/bin/sha256sum
$ sha256sum file
221a5de7399350b6c9061893437883c10308fdc498459ac717eafe8c202e61e1 file
$ sha256sum file > file.sum
$ sha256sum -c file.sum
file: OK
Code: Alles auswählen
$ sha256sum dir_mit_files/ -file -type f
sha256sum: ungültige Option -- „f“
„sha256sum --help“ gibt weitere Informationen.
Welche Datei file.ext, deren Format, Inhalt?#Pruefsumme aus file.ext letzter Teil abgeschnitten
Oben angemeckerte Zeile 8:
was soll das machen?while [ read -r file in */desktop/ddd4/ ]
do
Ich übersetze mir das mal so
Code: Alles auswählen
while test read -r file in */desktop/ddd4/
do
Ich kenne sowas
Code: Alles auswählen
$ echo aa bb cc | while read i o p ; do echo II $i OO $o PP $p; done
II aa OO bb PP cc
Was soll da mit den Ordnern */desktop/ddd4/ gemacht werden?NAME
read - read a line from standard input
SYNOPSIS
read [-r] var...
....
Das reime ich mir in etwa so zusammen:sha256sum ordner2 -file -type f | cp -u /ordner1
Code: Alles auswählen
$ echo file.sum | cp -u file.copy
cp: Fehlender Zieldatei‐Operand hinter „file.copy“
„cp --help“ gibt weitere Informationen.
Was ist seen[$0] ?Daher bevorzuge ich diesen link http://www.clug.in-chemnitz.de/vortraege/awk/
Also hier die angelesene awk-Zeile
awk '!seen[$0]++' filename
Code: Alles auswählen
$ man awk | grep -i seen -C1
variable (e.g., ENVIRON["HOME"] might be /home/arnold). Changing this array
does not affect the environment seen by programs which gawk spawns via redi‐
rection or the system() function.
--
NR The total number of input records seen so far.
Code: Alles auswählen
$ seen=(aaa bbb ccc ddd)
$ echo ${seen[2]}
ccc
Code: Alles auswählen
cat filename | awk '!seen[$0]++'
Die Programme aus md5deep
- /usr/bin/hashdeep
/usr/bin/md5deep
/usr/bin/sha1deep
/usr/bin/sha256deep
/usr/bin/tigerdeep
/usr/bin/whirlpooldeep
der hier vielleicht den Zweck erfüllt (der sich mir aber noch nicht erschließt).
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
- habakug
- Moderator
- Beiträge: 4314
- Registriert: 23.10.2004 13:08:41
- Lizenz eigener Beiträge: MIT Lizenz
Re: awk und noch was
Hallo!
Gruss, habakug
[1] http://www.gnu.org/software/gawk/manual ... rray-Intro
Es gibt in awk "assoziative Arrays" [1]. Das ist eine coole Sache, der Name ist frei wählbar. Um z.B. doppelt vorkommende Zeilen nur einmal anzeigen zu lassen etwa so:Was ist seen[$0] ?
Code: Alles auswählen
$ cat zeilen.txt
Zeile 1
Zeile 2
Zeile 3
Zeile 1
Zeile 4
Zeile 1
Zeile 2
Zeile 3
Zeile 1
Zeile 4
Zeile 1
$ awk 'seen[$0]++ == 1' zeilen.txt
Zeile 1
Zeile 2
Zeile 3
Zeile 4
$ awk 'google[$0]++ == 1' zeilen.txt
Zeile 1
Zeile 2
Zeile 3
Zeile 4
[1] http://www.gnu.org/software/gawk/manual ... rray-Intro
Re: awk und noch was
Ich denke, dass nur ``#!/bin/bash'' gemeint ist. (Das ``+x'' kommt sicher von ``chmod +x script''.)rendegast hat geschrieben:-> '#!/bin/bash +x'Code: Alles auswählen
$ ./test.dfde.bash bash: ./test.dfde.bash: bin/bash: Defekter Interpreter: Datei oder Verzeichnis nicht gefunden
Urspruenglich hat der fuehrende Slash gefehlt, der den Pfad absolut macht. Damit wurde vom aktuellen Verzeichnis ausgehend kein ``bin/bash'' gefunden.
http://marmaro.de/lue/txt/2014-02-25.txtkönnte natürlich auch eine tricky awk-Funktion sein, so tief bin ich nie in awk gewesen.Code: Alles auswählen
cat filename | awk '!seen[$0]++'
Use ed once in a while!
-
- Beiträge: 174
- Registriert: 29.04.2012 22:55:06
------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:49:32, insgesamt 1-mal geändert.
-
- Beiträge: 174
- Registriert: 29.04.2012 22:55:06
------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:50:03, insgesamt 2-mal geändert.
-
- Beiträge: 174
- Registriert: 29.04.2012 22:55:06
------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:50:34, insgesamt 1-mal geändert.
Re: awk und noch was
<->find /home/webster/Desktop/transport -type f -exec sha256sum {} \; | awk -F ' ' '!seen[$0]++' /home/webster/Desktop/transport;
awk '!seen[$0]++' filename
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-
- Beiträge: 174
- Registriert: 29.04.2012 22:55:06
------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:51:10, insgesamt 1-mal geändert.
Re: (gelöst) awk und noch was
Kann das so jetzt nicht in 'man bash' finden. Ein SkriptWenn ich das sog. builtin $FILENAME ...
Code: Alles auswählen
#!/bin/bash
set | egrep -i "BASH_VERSION|FILENAME"
Wenn FILENAME eine ungesetzte oder leere Variable ist, so analysiert awk den pipe-Stream.nehme, läuft es problemlos durch.Code: Alles auswählen
#!/bin/bash find /home/webster/Desktop/transport -type f -exec sha256sum {} \; | awk -F ' ' '!seen[$0]++' $FILENAME;
Bezeichnet FILENAME eine Datei, so würde awk diese verarbeiten anstelle des pipe-Stream.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
- habakug
- Moderator
- Beiträge: 4314
- Registriert: 23.10.2004 13:08:41
- Lizenz eigener Beiträge: MIT Lizenz
Re: (gelöst) awk und noch was
Hallo!
Das FILENAME ohne $ (!) ist eine Builtin-Variable von awk. Sie enthält den Namen der aktuellen Eingabe-Datei. Siehe "man awk" Kapitel "7. Builtin-variables".
Gruss, habakug
Das FILENAME ohne $ (!) ist eine Builtin-Variable von awk. Sie enthält den Namen der aktuellen Eingabe-Datei. Siehe "man awk" Kapitel "7. Builtin-variables".
Gruss, habakug
Re: (gelöst) awk und noch was
Gilt also nur innerhalb des awk-Kommandoblocks resp. eines awk-Skriptes,
nicht wie oben verwendet auf der bash-Commandline, in der Art
nicht wie oben verwendet auf der bash-Commandline, in der Art
Code: Alles auswählen
$ cat test
456
$ FILE=test
$ echo 123 | awk '{print $0,FILENAME}' $FILE
456 test
$ FILE=
$ echo 123 | awk '{print $0,FILENAME}' $FILE
123 -
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
Re: awk und noch was
Im Bezug auf awk geht's hier ja drunter und drueber ...
Bevor noch mehr geraetselt wird will ich diese Anweisung doch mal fuer euch zerlegen:
awk-Scripte sind Listen von Bedingung-Aktion-Paaren. Dieses Konstrukt ist eine Bedingung, die entscheidet ob die Standardaktion (= die Zeile ausgeben) ausgefuehrt wird oder nicht.
Entscheidend ist dabei, dass alles vom Seiteneffekt dieser Bedingung abhaengt. (Das ist typisch fuer C und C-aehnliche Sprachen, wie awk eine ist.)
Dann will ich mal die Bedingung zerlegen. Sie besteht aus:
1) Einer Negation: ``!''
2) Einem (assoziativen) Array: ``seen[ ]'' (In awk sind alle Arrays assoziativ.)
3) Dem Index in das Array: ``$0''
4) Und einem Post-Inkrement: ``++''
Die Auswertungsreihenfolge ist: Erst die Array-Indizierung dann die Negation. Was da raus kommt wird zurueck gegeben, ist also der Wert der Bedingung (0 oder der leere String -> false; alles andere ist true). Das Post-Inkrement wird erst danach ausgefuehrt. Es hat nur diesen Seiteneffekt, der entscheidend ist.
Zum Index: ``$0'' ist die Variable, die die aktuelle Zeile enthaelt. ``seen[$0]'' ist also ein Zugriff auf das Array an der Stelle, die den Schluessel mit dem Namen hat, der so lautet wie die aktuelle Zeile. Wenn in der Zeile ``foo'' steht, dann ist es ein Zugriff auf ``seen[foo]''; wenn die Zeile ``Das ist viel Text'' lautet, dann ist es ein Zugriff auf ``seen[Das ist viel Text]''.
Nicht existente Variablen oder Array-Eintraege sind false, was mittels der Negation true wird. Damit ist die Bedingung fuer alle diese Zeilen erfuellt, deren Textinhalt kein Index im Array ist. In diesen Faellen wir die Zeile ausgegeben. (Liesse man das ``++'' weg, dann wuerde das fuer alle Zeilen passieren. Das ist dann gleich wie bei cat(1).)
Das Post-Inkrement sorgt nun dafuer, dass der Wert im Array an der jeweiligen Stelle um Eins erhoeht wird. Der Initialwert ist 0, damit steigt er auf 1, 2, 3, usw. Er steigt jedes Mal, wenn eine weitere Zeile mit gleichem Inhalt eingelesen wird, denn dann wird der gleiche Array-Eintrag angesprochen.
Sobald der Wert aber einmal inkrementiert worden ist kann die Bedingung fuer diesen Eintrag nicht mehr wahr werden. Das sorgt dafuer, dass zwar jede Zeile einmal aber nicht oefter ausgegeben wird. In Konsequenz hat man ein Programm, das ``sort | uniq'' entspricht, nur dass zuvor nicht sortiert werden muss. Das hat z.B. den Vorteil, dass man nicht die komplette Eingabe lesen muss bevor man etwas ausgeben kann. Ein weiterer Vorteil des awk-Programms liegt darin, dass man es leicht abwandeln kann um z.B. all jene Zeilen auszugeben, die doppelt vorgekommen sind. (Gerade das macht das Beispiel auf der verlinkten Seite.)
Ich hoffe, hiermit ist euch dieses awk-Konstrukt etwas klarer geworden.
Dort steht aber noch ein ``== 1'' mit dabei und das ``!'' fehlt, weshalb die Erklaerung dort nicht ganz zur Verwendung hier passt.schorschruffneck hat geschrieben: Hier noch ein link, der diese awk-Schreibe benutzt und in kurzen Zügen sogar für mich awk verständlich macht.
http://biosimulations.org/diasc/awk_tutorial.html
Code: Alles auswählen
awk '!seen[$0]++'
awk-Scripte sind Listen von Bedingung-Aktion-Paaren. Dieses Konstrukt ist eine Bedingung, die entscheidet ob die Standardaktion (= die Zeile ausgeben) ausgefuehrt wird oder nicht.
Entscheidend ist dabei, dass alles vom Seiteneffekt dieser Bedingung abhaengt. (Das ist typisch fuer C und C-aehnliche Sprachen, wie awk eine ist.)
Dann will ich mal die Bedingung zerlegen. Sie besteht aus:
1) Einer Negation: ``!''
2) Einem (assoziativen) Array: ``seen[ ]'' (In awk sind alle Arrays assoziativ.)
3) Dem Index in das Array: ``$0''
4) Und einem Post-Inkrement: ``++''
Die Auswertungsreihenfolge ist: Erst die Array-Indizierung dann die Negation. Was da raus kommt wird zurueck gegeben, ist also der Wert der Bedingung (0 oder der leere String -> false; alles andere ist true). Das Post-Inkrement wird erst danach ausgefuehrt. Es hat nur diesen Seiteneffekt, der entscheidend ist.
Zum Index: ``$0'' ist die Variable, die die aktuelle Zeile enthaelt. ``seen[$0]'' ist also ein Zugriff auf das Array an der Stelle, die den Schluessel mit dem Namen hat, der so lautet wie die aktuelle Zeile. Wenn in der Zeile ``foo'' steht, dann ist es ein Zugriff auf ``seen[foo]''; wenn die Zeile ``Das ist viel Text'' lautet, dann ist es ein Zugriff auf ``seen[Das ist viel Text]''.
Nicht existente Variablen oder Array-Eintraege sind false, was mittels der Negation true wird. Damit ist die Bedingung fuer alle diese Zeilen erfuellt, deren Textinhalt kein Index im Array ist. In diesen Faellen wir die Zeile ausgegeben. (Liesse man das ``++'' weg, dann wuerde das fuer alle Zeilen passieren. Das ist dann gleich wie bei cat(1).)
Das Post-Inkrement sorgt nun dafuer, dass der Wert im Array an der jeweiligen Stelle um Eins erhoeht wird. Der Initialwert ist 0, damit steigt er auf 1, 2, 3, usw. Er steigt jedes Mal, wenn eine weitere Zeile mit gleichem Inhalt eingelesen wird, denn dann wird der gleiche Array-Eintrag angesprochen.
Sobald der Wert aber einmal inkrementiert worden ist kann die Bedingung fuer diesen Eintrag nicht mehr wahr werden. Das sorgt dafuer, dass zwar jede Zeile einmal aber nicht oefter ausgegeben wird. In Konsequenz hat man ein Programm, das ``sort | uniq'' entspricht, nur dass zuvor nicht sortiert werden muss. Das hat z.B. den Vorteil, dass man nicht die komplette Eingabe lesen muss bevor man etwas ausgeben kann. Ein weiterer Vorteil des awk-Programms liegt darin, dass man es leicht abwandeln kann um z.B. all jene Zeilen auszugeben, die doppelt vorgekommen sind. (Gerade das macht das Beispiel auf der verlinkten Seite.)
Ich hoffe, hiermit ist euch dieses awk-Konstrukt etwas klarer geworden.
Use ed once in a while!
Re: (gelöst) awk und noch was
Schnell ist das Konstrukt, hier eine Datei mit 3.000.000 Zeilen,Meillo hat geschrieben: In Konsequenz hat man ein Programm, das ``sort | uniq'' entspricht,
'sort | uniq' 3sec, awk-Konstrukt 1,4sec.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
Re: (gelöst) awk und noch was
Das liegt daran, dass nicht sortiert wird. Das awk-Konstrukt erzeugt ja nicht das gleiche Ergebnis. Es laesst den Sortierschritt einfach aus.rendegast hat geschrieben:Schnell ist das Konstrukt, hier eine Datei mit 3.000.000 Zeilen,Meillo hat geschrieben: In Konsequenz hat man ein Programm, das ``sort | uniq'' entspricht,
'sort | uniq' 3sec, awk-Konstrukt 1,4sec.
Zudem braucht es weniger Speicher wenn Zeilen mehrfach vorkommen. Sort muss sich naemlich alle Zeilen merken. Das awk-Konstrukt muss sich nur jede unterschiedliche Zeile einmal merken. Das waere bei `sort -u' auch der Fall.
Nur aus Interesse: Teste doch nochmal mit `sort -u', sowohl auf sortierten als auch auf unsortieren, bzw. falsch rum sortierten Daten (die liefert `sort -R' bzw. `sort | tac' ... aber das weisst du ja). Und ebenso auf Daten mit mehrfachen Vorkommen und bereits uniq-ifizierten Daten.
Use ed once in a while!
Re: (gelöst) awk und noch was
Guter EinwurfMeillo hat geschrieben: Teste doch nochmal mit `sort -u',
1sec weniger, immer noch langsamer als awk.$ time { sort -u zeilen | wc -l ; }
289
real 0m2.185s
user 0m3.496s
sys 0m0.224s
<->$ sort zeilen > zeilen_sort
$ time { sort -u zeilen_sort | wc -l ; }
289
real 0m0.954s
user 0m1.128s
sys 0m0.196s
awk gibt sich keine Blöße:
Code: Alles auswählen
$ time { awk '!seen[$0]++' zeilen | wc -l ; }
289
real 0m1.381s
user 0m1.344s
sys 0m0.032s
$ time { awk '!seen[$0]++' zeilen_sort | wc -l ; }
289
real 0m1.294s
user 0m1.244s
sys 0m0.044s
awk intensiver lernen (diese Abschweifung im Thread gehört ja dazu) und merken/nachvollziehen,
oder mir irgendwie mit 'sort -u > uniq-Liste' / '[egrep|fgrep] [-m1] -f uniq-Liste ursprungsdatei' behelfen?
(erste Versuche klappen gar nicht) ('egrep -f' ist seeeehr langsam, für 100 Zeilen Log sollte es aber ausreichen)
Zuletzt geändert von rendegast am 24.05.2014 12:07:23, insgesamt 1-mal geändert.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
Re: (gelöst) awk und noch was
Das war zu erwarten, denn sort kann nun alle mehrfachen Zeilen ignorieren, wodurch weniger Daten gespeichert werden mussen. Und der uniq-Schritt passiert schon beim Aufnehmen der Zeile. Im Vergleich zu awk ist `sort -u' langsamer, da halt immer noch sortiert wird.rendegast hat geschrieben:1sec weniger, immer noch langsamer als awk.$ time { sort -u zeilen | wc -l ; }
289
real 0m2.185s
user 0m3.496s
sys 0m0.224s
Deine weiteren Messergebnisse entsprechen auch meinen Erwartungen: Bei den beiden sort-Varianten macht es einen Unterschied ob die Eingangsdaten schon sortiert sind oder nicht. Das laesst auf einen Sortieralgorithmus schliessen, der unterschiedliche Best-, Average- und Worst-Cases hat (wie Quicksort, der vermutlich verwendet wird). Beim awk-Ansatz macht es keinen Unterschied, da hierbei nicht sortiert wird. Damit ist die Reihenfolge der Eingangsdaten irrelevant.
Das Entweder-oder kann ich dir nicht beantworten; ich kann dich nur zum Sowohl-als-auch motivieren.Bleibt die (rhetorische) Frage, was kann ich! eher?
awk intensiver lernen (der Thread gehört ja dazu) und merken/nachvollziehen,
oder mir irgendwie mit 'sort -u > uniq-Liste' / 'grep -f uniq-Liste ursprungsdatei' behelfen?
('egrep -f' ist seeeehr langsam, für 100 Zeilen Log sollte es aber ausreichen).
Awk wird viel zu sehr totgesagt (im Gegensatz zu sed, uebrigens). Ich sehe in awk aber eine Sprache mit einem enorm guten Preis-Leistungs-Verhaeltnis. (Man kann sie innerhalb eines Tages lernen wenn man C und sed schon kennt.) In dieser Hinsicht kann Perl IMO nicht mithalten, wenn das auch in anderen Gebieten seine Staerken hat. Ich finde awk auch deutlich einfach als die Shell, da es aus einem Guss ist, was man bei der Shell kaum vertreten kann. (Ohne mich darauf festlegen lassen zu wollen, weil man sowas ja doch nicht entscheiden kann, wuerde ich awk durchaus als meine Lieblingssprache bezeichnen.)
Use ed once in a while!