garciam
Goto Top

PowerShell Json Suchen und Ersetzen

Hallo

Ich versuche die bookmarks Datei zu durchsuchen und einige Einträge zu löschen. Das Suchen und Ersetzen funktioniert grundsätzlich, jedoch nur bis eine neue Zeile kommt. Kann mir jemand sagen, wie ich das machen muss, damit ich über mehrere Zeilen suchen und ersetzen kann?

Ich habe z.B. folgende Zeilen in der bookmarks Datei. Nun möchte ich ab der geschweiften Klammer alles löschen.

"children": [ {
"date_added": "13227086606439531",
"guid": "93561719-8a22-4cfc-85b5-beef11e15d94",

(Get-Content bookmarks) | ForEach { $_ -Replace """date_added"":\s""[0-9]*"",", " " } | Set-Content "bookmarks2"  

Vielen Dank.

Content-Key: 628257

Url: https://administrator.de/contentid/628257

Ausgedruckt am: 29.03.2024 um 09:03 Uhr

Mitglied: 146707
146707 04.12.2020, aktualisiert am 05.12.2020 um 15:16:04 Uhr
Goto Top
Ich könnte dir das jetzt sagen (Get-Content liefert dir ein Array, das kannst du mit dem Parameter -raw umgehen dann kannst du zeilenübergreifend matchen) aber ich möchte dir hier extra eine bessere Methode bei solchen Sachen aufzeigen.
Das was du da hast ist eine JSON Datei und in solchen Dateien mit Regex-Replace zu arbeiten ist Fehleranfällig weil solche Dateien hinter auch weiterhin gültig sein müssen und weil man diese nativ mit Powershell parsen und bearbeiten und zurückschreiben kann, ist das in der Regel zu bevorzugen, guckst du dieses Beispiel
# JSON String kann natürlich auch aus einer Datei kommen, ist aber nur fürs Beispiel hier so aufgeführt
$string = @'  
{
    "children": [   
        {
            "date_added": "13227086606439531",  
            "guid": "93561719-8a22-4cfc-85b5-beef11e15d94"  
        }]
}
'@  
# JSON String zu einem Object konvertieren
$json = $string | ConvertFrom-Json
# Property des JSONs bearbeiten, in diesem Fall dem Knoten "children" ein leeres Array zuweisen 
$json.children = @()
# JSON Object wieder in einen JSON String wandeln was du dann wieder in eine Datei wegschreiben kannst (hier fürs Beipspiel weg gelassen).
$json | ConvertTo-Json -Depth 100

Ergebnis
{
    "children":  
}
Du siehst das ist erstens klarer aufgebaut, sicherer und wartungsfreundlicher.
Damit kannst du auch gezielt einzelne Knoten und Properties schön komfortabel bearbeiten ohne mit Regex hantieren zu müssen oder sich gg. Fehler einzubauen.

Gruß p.
Mitglied: garciam
garciam 07.12.2020 aktualisiert um 08:30:26 Uhr
Goto Top
Hallo primal

Danke für deinen Ansatz. Das ist bestimmt der richtige Weg, ich bin aber sehr schlecht mit PowerShell, Arrays, usw. Über children kann ich nicht bestimmen welche Favoriten gelöscht werden sollen und welche nicht. In den Favoriten gibt es einen Ordner "Allgemein", dieser und alle darin enthaltenen Favoriten möchte ich löschen. Ich müsste dies also über den Name machen können, denke ich.

Die Bookmarks Datei ist folgendermassen aufgebaut:

{
"checksum": "451b0f33043ebbc73b1b4cd713c40dd7",
"roots": {
"bookmark_bar": {
"children": [ {
"date_added": "13228425144239994",
"guid": "bc3e3360-9987-4fd7-86b0-36579989366e",
"id": "5",
"name": "Favorit01",
"show_icon": false,
"source": "import_fre",
"type": "url",
"url": "http://go.favorit01/9095"
} ],
"date_added": "13232094767386493",
"date_modified": "13249488022274696",
"guid": "00000000-0000-4000-a000-000000000002",
"id": "1",
"name": "Favoritenleiste",
"source": "unknown",
"type": "folder"
},
"other": {
"children": [ {
"children": [ {
"date_added": "13228425144239994",
"guid": "a054e20f-a1c0-4c5a-a02c-25263584cdd6",
"id": "8",
"name": "Favorit02",
"show_icon": false,
"source": "import_fre",
"type": "url",
"url": "https://www.favorit02/Extranet"
}, {
"date_added": "13228425144239994",
"guid": "b329e2fa-598a-4bee-bc23-a3c220b2c21a",
"id": "9",
"name": "Favorit03",
"show_icon": false,
"source": "import_fre",
"type": "url",
"url": "http://intranet.favorit03/"
}, {
"date_added": "13228425144239994",
"guid": "5fb5e6e8-269c-406a-aec0-07ec8c97af0c",
"id": "10",
"name": "Favorit04",
"show_icon": false,
"source": "import_fre",
"type": "url",
"url": "http://favorit04/login.aspx"
}],
"date_added": "13232094772042553",
"date_modified": "0",
"guid": "596645bd-206e-4f21-99e1-11c5e777b829",
"id": "7",
"name": "Allgemein",
"source": "import_fre",
"type": "folder"
}, {
"children": [ {
"date_added": "13228425144255622",
"guid": "b8914a50-752d-46f0-ac7e-a84b7a453aba",
"id": "21",
"name": "Favorit05",
"show_icon": false,
"source": "import_fre",
"type": "url",
"url": "http://favorit05"
}, {
"date_added": "13228425144255622",
"guid": "ac5a9e3e-5232-4af4-b5a1-36a1720cd264",
"id": "22",
"name": "Favorit06",
"show_icon": false,
"source": "import_fre",
"type": "url",
"url": "https://favorit06:8181/"
...

07-12-_2020_08-21-09


Für weitere Tipps wäre ich dir Dankbar.

Gruss
Mitglied: 146707
Lösung 146707 07.12.2020 aktualisiert um 11:00:34 Uhr
Goto Top
Für weitere Tipps wäre ich dir Dankbar.
Gerne.
Ein einfaches Where-Object reicht dir hier zum Ausfiltern der jeweiligen Objects:
# ....
$json.roots.other.children = $json.roots.other.children | ?{!($_.Name -eq 'Allgemein' -and $_.type -eq 'folder')}  
# ....
Nur zur Info: Nicht vergessen den "checksum" Knoten zu löschen, sonst mag Edge das angepasste File nicht mehr face-wink

Also in Gänze würde ein Anpassen des Bookmark-Files des aktuellen Users für deinen Fall so aussehen: (inkl. Löschen der "checksum"-Property)
$file = "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\Bookmarks"  
$json = gc $file | ConvertFrom-Json
$json.roots.other.children = $json.roots.other.children | ?{!($_.Name -eq 'Allgemein' -and $_.type -eq 'folder')}  
$json | select * -Exclude checksum | ConvertTo-Json -Depth 100 | sc $file

G. p.
Mitglied: garciam
garciam 07.12.2020 um 11:54:06 Uhr
Goto Top
Hallo Primal

Ich habe auch noch etwas rumprobiert, jedoch nicht so wirklich mit Erfolg.

Dein Script sieht gut aus und scheint zu funktionieren face-smile

Super, vielen Dank!!!

Gruss
Mitglied: 146707
146707 07.12.2020 aktualisiert um 11:56:53 Uhr
Goto Top
Schön. Dann bitte auch den Beitrag schließen. Thanks.

G. p.
Mitglied: garciam
garciam 07.12.2020 um 13:00:01 Uhr
Goto Top
Klar, wollte nur noch kurz testen bevor ich schliesse.