|
fireworker72
Anmeldungsdatum: 11. März 2017
Beiträge: 64
|
Hallo an alle Ich bin neu hier und hätte eine Frage an die Profis Ich habe eine Datei mit 3 Abschnitten Anfang accountName Ende Leeerzeile Die Leerzeilen hab Ich schon mit sed eingefügt Wie gehe Ich es am besten an wenn Ich die Abschnitte je in eine Datei speichern möchte jetzt nimmt er immer alle 3 Abschnitte LG Peter Moderiert von rklm: Titel aussagekräftiger gemacht
|
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17630
|
| for user in Peter Paul Mary; do sed -n "/$user/,/^$/p" sample.rc > $user.rc ; done
|
Testdatenerzeugung:
| user=(Peter Paul Mary); for n in {1..3}; do echo -e "${user[$n]}\nfoo=$n\nbar=$((240/(n+1)))\nfasel=dingeling\nfoobar=$((3*n+7))\n" ; done > sample.rc
|
Testdaten:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | cat sample.rc
Peter
foo=0
bar=120
fasel=dingeling
foobar=7
Paul
foo=1
bar=80
fasel=dingeling
foobar=10
Mary
foo=2
bar=60
fasel=dingeling
foobar=13
|
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13242
|
fireworker72 schrieb: Hallo an alle Ich bin neu hier und hätte eine Frage an die Profis
Herzlich willkommen hier im Forum!
Ich habe eine Datei mit 3 Abschnitten Anfang accountName Ende Leeerzeile
Kannst Du mal Beispieldaten zeigen? Dann müssen wir nicht raten.
Die Leerzeilen hab Ich schon mit sed eingefügt
Warum fügst Du erst noch Leerzeilen ein, wenn Du die Inhalte doch auf mehrere Dateien verteilen willst?
Wie gehe Ich es am besten an wenn Ich die Abschnitte je in eine Datei speichern möchte jetzt nimmt er immer alle 3 Abschnitte
Gibt es irgendwelche Regeln, wie die Dateien benannt werden sollen? Und brauchst Du das als Skript oder ist das eine einmalige Sache? In letzterem Fall kann man das vermutlich mit vim recht einfach machen.
|
|
fireworker72
(Themenstarter)
Anmeldungsdatum: 11. März 2017
Beiträge: 64
|
Danke erstmal für die Infos die Leerzeilen hab Ich eingefügt um Blöcke zu erhalten dachte das wär dann einfacher 😉 Hintergrund ist: damit möchte Ich die Daten meiner Amzon (Alexa Echo/Dot) Geräte auslesen, ein Raspberry verarbeitet die Daten dann mit meinem Smarthome weiter und steuert die Geräte dann, dafür werden aber diese Werte benötigt. Ich würde aus jedem Block accountName:xxxxxxx alles was mit device:xxxx anfängt und die serialNumber:xxxxx benötigen, und das pro Block in einer Datei z.B.: device1.txt device2.txt device3.txt (müssen aber nicht so heißen) inhalt der Datei
accountName:xxxxxxx
appDeviceList:[]
capabilities:[
CHANGE_NAME
EARCONS
SLEEP
UPDATE_WIFI
CUSTOM_ALARM_TONE
AUDIO_PLAYER
REQUIRES_OOBE_FOR_SETUP
PANDORA
TIMERS_AND_ALARMS
TUNE_IN
SET_LOCALE
SALMON
PAIR_REMOTE
FAR_FIELD_WAKE_WORD
PERSISTENT_CONNECTION
POPTART
DREAM_TRAINING
AUDIBLE
SUPPORTS_SOFTWARE_VERSION
SUPPORTS_CONNECTED_HOME_ALL
PAIR_BT_SINK
PAIR_BT_SOURCE]
charging:null
clusterMembers:[]
deviceAccountId:xxxxxxxxxxxxxx
deviceOwnerCustomerId:xxxxxxxx
deviceType:A3Sxxxxxxxxxxxxxxxxx
essid:
language:null
macAddress:
online:true
parentClusters:[]
postalCode:null
registrationId:null
remainingBatteryLevel:null
serialNumber:xxxxxxxxxxx
softwareVersion:571207720]
accountName:yyyyyyy
appDeviceList:[]
capabilities:[
CHANGE_NAME
EARCONS
SLEEP
UPDATE_WIFI
CUSTOM_ALARM_TONE
AUDIO_PLAYER
REQUIRES_OOBE_FOR_SETUP
PANDORA
TIMERS_AND_ALARMS
TUNE_IN
SET_LOCALE
SALMON
PAIR_REMOTE
FAR_FIELD_WAKE_WORD
PERSISTENT_CONNECTION
POPTART
DREAM_TRAINING
AUDIBLE
SUPPORTS_SOFTWARE_VERSION
SUPPORTS_CONNECTED_HOME_ALL
PAIR_BT_SINK
PAIR_BT_SOURCE]
charging:null
clusterMembers:[]
deviceAccountId:yyyyyyy
deviceOwnerCustomerId:yyyyyyy
deviceType:A3Syyyyyyy
essid:
language:null
macAddress:
online:true
parentClusters:[]
postalCode:null
registrationId:null
remainingBatteryLevel:null
serialNumber:yyyyyyy
softwareVersion:571207720]
accountName:zzzzzzzzz
appDeviceList:[]
capabilities:[
CHANGE_NAME
EARCONS
SLEEP
UPDATE_WIFI
CUSTOM_ALARM_TONE
AUDIO_PLAYER
REQUIRES_OOBE_FOR_SETUP
PANDORA
TIMERS_AND_ALARMS
TUNE_IN
SET_LOCALE
SALMON
PAIR_REMOTE
FAR_FIELD_WAKE_WORD
PERSISTENT_CONNECTION
POPTART
DREAM_TRAINING
AUDIBLE
SUPPORTS_SOFTWARE_VERSION
SUPPORTS_CONNECTED_HOME_ALL
PAIR_BT_SINK
PAIR_BT_SOURCE]
charging:null
clusterMembers:[]
deviceAccountId:zzzzzzzzz
deviceOwnerCustomerId:zzzzzzzzz
deviceType:A3Szzzzzzzzzzzzzzz
essid:
language:null
macAddress:
online:true
parentClusters:[]
postalCode:null
registrationId:null
remainingBatteryLevel:null
serialNumber:zzzzzzzzzzz
softwareVersion:571207720] LG Peter Bearbeitet von sebix: Bitte verwende in Zukunft Codeblöcke, um die Übersicht im Forum zu verbessern!
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13242
|
fireworker72 schrieb:
die Leerzeilen hab Ich eingefügt um Blöcke zu erhalten dachte das wär dann einfacher 😉
Nee, ist es nicht. Du musst ja die Zeilen automatisch erkennen, hinter oder vor denen Du eine Leerzeile einfügst. Die gleiche Erkennung kannst Du auch nutzen um die Aufteilung auf mehrere Dateien zu machen.
Ich würde aus jedem Block accountName:xxxxxxx alles was mit device:xxxx anfängt und die serialNumber:xxxxx benötigen, und das pro Block in einer Datei z.B.: device1.txt device2.txt device3.txt (müssen aber nicht so heißen) inhalt der Datei
Das ist ein awk-Einzeiler: | awk -F: '$1 == "accountName" {out=$2 ".txt"} {print >out}' eingabe-datei
|
Erläuterung: "-F:" setzt den Feldtrenner auf ":". "$1 == "accountName" erfasst alle Zeilen, deren erstes Feld "accountName" enthält. "{out=$2 ".txt"}" merkt sich den Account-Namen mit angehängtem ".txt" in der Variable "out". "{print >out}" gibt für jede Zeile den gesamten Inhalt in die Datei aus, die den Namen hat, der in out gespeichert ist.
|
|
fireworker72
(Themenstarter)
Anmeldungsdatum: 11. März 2017
Beiträge: 64
|
Hallo wenn Ich das eingebe awk -F: '$1 == "accountName" {out=$2 ".txt"} {print > out}' curl2.txtbekomme Ich folgende Fehlermeldung awk: cannot open "" for output (No such file or directory) das Verzeichniss und die Datei haben Schreib/Leseberechtigungen Wenn das funktioniert sollte er 3 Dateien anlegen mit dem Namen und Inhalt accountName richtig? aber wie bekomme Ich aus dem ersten Block dann deciceAccount deviceOwner deviceType und SerialNummber noch in die selbe Datei bzw. die selben Daten aus dem zweiten Block in die zweite Datei?
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13242
|
fireworker72 schrieb:
bekomme Ich folgende Fehlermeldung awk: cannot open "" for output (No such file or directory)
Ein möglicher Grund ist die awk-Version. Gibt doch mal ein: | $ ls -il $(type -p awk mawk gawk nawk)
262225 lrwxrwxrwx 1 root root 21 Dez 8 2013 /usr/bin/awk -> /etc/alternatives/awk*
271331 -rwxr-xr-x 1 root root 117768 Mär 24 2014 /usr/bin/mawk*
262835 lrwxrwxrwx 1 root root 22 Dez 8 2013 /usr/bin/nawk -> /etc/alternatives/nawk*
|
Bei mir werkelt da also der mawk. Der andere ist, dass der Inhalt der Datei anders ist als das, was Du präsentiert hast. Du musst schon die echten Eingabedaten liefern.
das Verzeichniss und die Datei haben Schreib/Leseberechtigungen
Hat mit Rechten nix zu tun: es kann einfach keine leeren Dateinamen geben. Das ist von der Fehlermeldung her klar.
Wenn das funktioniert sollte er 3 Dateien anlegen mit dem Namen und Inhalt accountName richtig?
Korrekt.
aber wie bekomme Ich aus dem ersten Block dann deciceAccount deviceOwner deviceType und SerialNummber noch in die selbe Datei bzw. die selben Daten aus dem zweiten Block in die zweite Datei?
Ich verstehe die Frage nicht. Der Einzeiler macht (bei mir) genau das, was Du angefragt hast: die Blöcke werden auf je eine Datei pro "accountName" aufgeteilt.
|
|
schusch
Anmeldungsdatum: 2. September 2008
Beiträge: 324
|
Steht in der 1.Zeile der Datei eine Zeile der Form
accountName:irgendeinName
? Sonst ist out bei der Ausgabe der ersten Zeile ="". Gibt es eine Zeile der Form
accountName:
? Dann ist out ab dieser Zeile ="".
|
|
fireworker72
(Themenstarter)
Anmeldungsdatum: 11. März 2017
Beiträge: 64
|
Danke meine Herren funktioniert *freu* es war am Dateianfang noch eine eckige Klammer so jetzt hab Ich meine 3 Dateien jetzt müsste ich nur noch alles rauslöschen bis auf
accountName:BlaBlaBla
deviceAccountId:BlaBlaBla
deviceOwnerCustomerId:BlaBlaBla
deviceType:BlaBlaBla
serialNumber:BlaBlaBla
geht das irgendwie auf einmal? oder kann man das im
awk -F: '$1 == "accountName" {out=$2 ".txt"} {print >out}' curl2.txt
Befehl schon irgendwie integrieren damit er die anderen Zeilen erst gar nicht in die Datei schreibt? mit Zeilen zählen geht es nicht, da die Zeilenanzahl nicht immer Ident ist Danke und LG Peter
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13242
|
fireworker72 schrieb:
accountName:BlaBlaBla
deviceAccountId:BlaBlaBla
deviceOwnerCustomerId:BlaBlaBla
deviceType:BlaBlaBla
serialNumber:BlaBlaBla
geht das irgendwie auf einmal? oder kann man das im [...]
Befehl schon irgendwie integrieren damit er die anderen Zeilen erst gar nicht in die Datei schreibt? mit Zeilen zählen geht es nicht, da die Zeilenanzahl nicht immer Ident ist
Du kommst immer häppchenweise mit neuen Anforderungen. Es wäre hilfreicher, wenn Du das gleich am Anfang klar gemacht hättest. Du musst nur einen entsprechenden Regulären Ausdruck vor den zweiten Block packen, so dass der nur für die Zeilen gilt, die Du geschrieben haben willst.
|
|
fireworker72
(Themenstarter)
Anmeldungsdatum: 11. März 2017
Beiträge: 64
|
Sorry Hab Ich aber eigentlich weiter oben geschrieben "Ich würde aus jedem Block accountName:xxxxxxx alles was mit device:xxxx anfängt und die serialNumber:xxxxx benötigen, und das pro Block in einer Datei z.B.: device1.txt device2.txt device3.txt (müssen aber nicht so heißen)" das check i jetzt irgendwie net!? "Du musst nur einen entsprechenden Regulären Ausdruck vor den zweiten Block packen, so dass der nur für die Zeilen gilt, die Du geschrieben haben willst." LG
|
|
schusch
Anmeldungsdatum: 2. September 2008
Beiträge: 324
|
| awk -F: '/^accountName:/ {
out=$2 ".txt"
print >out
}
/^device:/ { print >>out}
/^serialNumber:/ { print >>out}
' <EingabeDatei
|
Man hilft ja gerne ☺
|
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
|
Hi Peter, zuerst auch mal von mir ein herzliches Willkommen hier auf dem Forum ! fireworker72 schrieb: ... alles rauslöschen bis auf
accountName:BlaBlaBla
deviceAccountId:BlaBlaBla
deviceOwnerCustomerId:BlaBlaBla
deviceType:BlaBlaBla
serialNumber:BlaBlaBla
geht das irgendwie auf einmal? ...
Ich würde es umgekehrt machen: nur die Zeilen drucken, die Du haben willst. Die Anderen haben auch schon das Stichwort dafür fallen lassen: sowas geht mit Regulären Ausrücken. Klar kannst Du die entsprechend einbauen: (so ist das bei awk eigentlich sowieso gedacht) awk -F: '$1 == "accountName" {out=$2 ".txt"; print > out} /^device/ || /^serialNumber:/ {print >> out}' curl2.txt
Das ist im Prinzip das selbe was schusch auch schon schreibt, nur habe ich es noch ein bisschen zusammengefasst. Und ich lasse alle Zeilen durchgehen, die mit "device" anfangen. (nach Deinem Beispiel dachte ich, das passt schon) LG, track
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13242
|
track schrieb:
awk -F: '$1 == "accountName" {out=$2 ".txt"; print > out} /^device/ || /^serialNumber:/ {print >> out}' curl2.txt
Kann man dann auch zusammenfassen und ich würde die Ausgabe nicht duplizieren: | awk -F: '$1 == "accountName" {out=$2 ".txt"} /^(device|serialNumber:|accountName:)/ {print >> out}' curl2.txt
|
|
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
|
Nee, die Trennung, dass er die Datei bei der Schlüsselzeile mit dem "accountName" echt neu schreibt, habe ich bewusst so gelassen. Denn sonst würde er bei jedem neuen Versuch die Daten an die schon vorhandenen Dateien anhängen (und nicht neu beginnen). Dann hättest Du womöglich am Ende den Datenblock 5x in der Datei stehen ... 😉 LG, track
|