------------------------------------------------------------

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
schorschruffneck
Beiträge: 174
Registriert: 29.04.2012 22:55:06

------------------------------------------------------------

Beitrag von schorschruffneck » 21.05.2014 02:54:05

--------------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:48:44, insgesamt 2-mal geändert.

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: awk und noch was

Beitrag von rendegast » 21.05.2014 06:55:41

Meine Ausgabe am Terminal bleibt leer.
(Ein Testverzeichnis mit einigen Ordnern */desktop/ddd4/ und Dateien)

Code: Alles auswählen

$ ./test.dfde.bash
bash: ./test.dfde.bash: bin/bash: Defekter Interpreter: Datei oder Verzeichnis nicht gefunden
-> '#!/bin/bash +x'

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'
-> 'for $((proof+1)) ; do echo "ZAEHLER" $proof; done'

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.

proof=$(sha256sum file -type f -name)
...
sha256sum file -type f | ....
was soll das machen?
'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.
#Pruefsumme aus file.ext letzter Teil abgeschnitten
Welche Datei file.ext, deren Format, Inhalt?



Oben angemeckerte Zeile 8:
while [ read -r file in */desktop/ddd4/ ]
do
was soll das machen?
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
NAME
read - read a line from standard input

SYNOPSIS
read [-r] var...
....
Was soll da mit den Ordnern */desktop/ddd4/ gemacht werden?


sha256sum ordner2 -file -type f | cp -u /ordner1
Das reime ich mir in etwa so zusammen:

Code: Alles auswählen

$ echo file.sum | cp -u file.copy
cp: Fehlender Zieldatei‐Operand hinter „file.copy“
„cp --help“ gibt weitere Informationen.
(?)


Daher bevorzuge ich diesen link http://www.clug.in-chemnitz.de/vortraege/awk/
Also hier die angelesene awk-Zeile

awk '!seen[$0]++' filename
Was ist seen[$0] ?

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.
Oder soll seen[$0] vielleicht ein Element eines bash-Arrays seen sein?

Code: Alles auswählen

$ seen=(aaa bbb ccc ddd)
$ echo ${seen[2]}
ccc
Dann sollte Datei filename aber wohl nur Zahlen beinhalten.

Code: Alles auswählen

cat filename | awk '!seen[$0]++' 
könnte natürlich auch eine tricky awk-Funktion sein, so tief bin ich nie in awk gewesen.





Die Programme aus Debianmd5deep
  • /usr/bin/hashdeep
    /usr/bin/md5deep
    /usr/bin/sha1deep
    /usr/bin/sha256deep
    /usr/bin/tigerdeep
    /usr/bin/whirlpooldeep
(arbeiten auch rekursiv) haben einen ungewohnten evtl. verwirrenden Check-Modus, genannt "match",
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")

Benutzeravatar
habakug
Moderator
Beiträge: 4313
Registriert: 23.10.2004 13:08:41
Lizenz eigener Beiträge: MIT Lizenz

Re: awk und noch was

Beitrag von habakug » 21.05.2014 08:46:03

Hallo!
Was ist seen[$0] ?
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:

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
Gruss, habakug

[1] http://www.gnu.org/software/gawk/manual ... rray-Intro
( # = root | $ = user | !! = mod ) (Vor der PN) (Debianforum-Wiki) (NoPaste)

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: awk und noch was

Beitrag von Meillo » 21.05.2014 11:55:47

rendegast hat geschrieben:

Code: Alles auswählen

$ ./test.dfde.bash
bash: ./test.dfde.bash: bin/bash: Defekter Interpreter: Datei oder Verzeichnis nicht gefunden
-> '#!/bin/bash +x'
Ich denke, dass nur ``#!/bin/bash'' gemeint ist. (Das ``+x'' kommt sicher von ``chmod +x script''.)

Urspruenglich hat der fuehrende Slash gefehlt, der den Pfad absolut macht. Damit wurde vom aktuellen Verzeichnis ausgehend kein ``bin/bash'' gefunden.

Code: Alles auswählen

cat filename | awk '!seen[$0]++' 
könnte natürlich auch eine tricky awk-Funktion sein, so tief bin ich nie in awk gewesen.
http://marmaro.de/lue/txt/2014-02-25.txt ;-)
Use ed once in a while!

schorschruffneck
Beiträge: 174
Registriert: 29.04.2012 22:55:06

------------------------------------------------------------

Beitrag von schorschruffneck » 21.05.2014 15:27:38

--------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:49:32, insgesamt 1-mal geändert.

schorschruffneck
Beiträge: 174
Registriert: 29.04.2012 22:55:06

------------------------------------------------------------

Beitrag von schorschruffneck » 21.05.2014 21:29:23

-----------------------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:50:03, insgesamt 2-mal geändert.

schorschruffneck
Beiträge: 174
Registriert: 29.04.2012 22:55:06

------------------------------------------------------------

Beitrag von schorschruffneck » 22.05.2014 03:06:38

---------------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:50:34, insgesamt 1-mal geändert.

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: awk und noch was

Beitrag von rendegast » 22.05.2014 04:08:40

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")

schorschruffneck
Beiträge: 174
Registriert: 29.04.2012 22:55:06

------------------------------------------------------------

Beitrag von schorschruffneck » 22.05.2014 08:22:20

-----------------------------------------------------------------------------------------------------------------------------------------------------------
Zuletzt geändert von schorschruffneck am 06.06.2014 09:51:10, insgesamt 1-mal geändert.

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: (gelöst) awk und noch was

Beitrag von rendegast » 22.05.2014 10:46:36

Wenn ich das sog. builtin $FILENAME ...
Kann das so jetzt nicht in 'man bash' finden. Ein Skript

Code: Alles auswählen

#!/bin/bash
set | egrep -i "BASH_VERSION|FILENAME"
spuckt nur BASH_VERSION aus.

Code: Alles auswählen

#!/bin/bash
find /home/webster/Desktop/transport -type f -exec sha256sum {} \;  | awk -F ' ' '!seen[$0]++' $FILENAME;
nehme, läuft es problemlos durch.
Wenn FILENAME eine ungesetzte oder leere Variable ist, so analysiert awk den pipe-Stream.
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")

Benutzeravatar
habakug
Moderator
Beiträge: 4313
Registriert: 23.10.2004 13:08:41
Lizenz eigener Beiträge: MIT Lizenz

Re: (gelöst) awk und noch was

Beitrag von habakug » 22.05.2014 10:56:40

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
( # = root | $ = user | !! = mod ) (Vor der PN) (Debianforum-Wiki) (NoPaste)

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: (gelöst) awk und noch was

Beitrag von rendegast » 22.05.2014 13:09:25

Gilt also nur innerhalb des awk-Kommandoblocks resp. eines awk-Skriptes,
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")

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: awk und noch was

Beitrag von Meillo » 23.05.2014 23:01:27

Im Bezug auf awk geht's hier ja drunter und drueber ...

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
Dort steht aber noch ein ``== 1'' mit dabei und das ``!'' fehlt, weshalb die Erklaerung dort nicht ganz zur Verwendung hier passt.

Code: Alles auswählen

awk '!seen[$0]++'
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.
Use ed once in a while!

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: (gelöst) awk und noch was

Beitrag von rendegast » 24.05.2014 07:33:13

Meillo hat geschrieben: In Konsequenz hat man ein Programm, das ``sort | uniq'' entspricht,
Schnell ist das Konstrukt, hier eine Datei mit 3.000.000 Zeilen,
'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")

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: (gelöst) awk und noch was

Beitrag von Meillo » 24.05.2014 08:36:45

rendegast hat geschrieben:
Meillo hat geschrieben: In Konsequenz hat man ein Programm, das ``sort | uniq'' entspricht,
Schnell ist das Konstrukt, hier eine Datei mit 3.000.000 Zeilen,
'sort | uniq' 3sec, awk-Konstrukt 1,4sec.
Das liegt daran, dass nicht sortiert wird. Das awk-Konstrukt erzeugt ja nicht das gleiche Ergebnis. Es laesst den Sortierschritt einfach aus.

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!

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: (gelöst) awk und noch was

Beitrag von rendegast » 24.05.2014 09:41:54

Meillo hat geschrieben: Teste doch nochmal mit `sort -u',
Guter Einwurf
$ time { sort -u zeilen | wc -l ; }
289

real 0m2.185s
user 0m3.496s
sys 0m0.224s
1sec weniger, immer noch langsamer als awk.
$ 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
Bleibt die (rhetorische) Frage, was kann ich! eher?
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")

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: (gelöst) awk und noch was

Beitrag von Meillo » 24.05.2014 10:40:00

rendegast hat geschrieben:
$ time { sort -u zeilen | wc -l ; }
289

real 0m2.185s
user 0m3.496s
sys 0m0.224s
1sec weniger, immer noch langsamer als awk.
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.


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.

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).
Das Entweder-oder kann ich dir nicht beantworten; ich kann dich nur zum Sowohl-als-auch motivieren. ;-)

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!

Antworten