我正在尝试使用 Powershell 将 Chrome 书签导出到 CSV/Excel。我遇到了关于创建不正确的 JSON 文件的障碍。这是由于 Chrome 中有两组文件夹,称为 Bookmark_Bar 和 Synced。
BookMark_Bar 创建一个带有括号的 JSON,如下所示:
[
{
},
{
}
]
同步文件夹还在同一文件中创建如下一组数据:
[
{
},
{
}
]
代码如下。
$isodate = Get-Date -Format yyyymmmdd_hhmmss
$logFilePath = "d:\PowerShell_$isodate.log"
# ############################
Start-Transcript -Path $logFilePath -Append
#########################################
#Declare Variables
$pathToJsonFile = "$env:localappdata\Google\Chrome\User Data\Default\Bookmarks"
#$JsonFilePath = "D:\04. PowerShell\BookMarks\ChromeBookMarx.json"
#$OutputFilePath = "D:\BookMarx.csv"
$data = Get-content $pathToJsonFile | out-string | ConvertFrom-Json
Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"
#A nested function to enumerate bookmark folders
Function Get-BookmarkFolder {
[cmdletbinding()]
Param(
[Parameter(Position=0,ValueFromPipeline=$True)]
$Node
)
Process
{
foreach ($child in $node.children)
{
#get parent folder name
$parent = $node.Name
if ($child.type -eq 'Folder')
{
Write-Verbose "Processing $($child.Name)"
Get-BookmarkFolder $child
}
else
{
$hash= [ordered]@{
Folder = $parent
Name = $child.name
URL = $child.url
Added = [datetime]::FromFileTime(([double]$child.Date_Added)*10)
}
#write custom object
New-Object -TypeName PSobject -Property $hash
} #else url
} #foreach
} #process
} #end function
#create a new JSON file
$text | Set-Content 'file.json'
$test1 = '{
"markers":' | Add-Content 'file.json'
#these should be the top level "folders"
$data.roots.bookmark_bar | Get-BookmarkFolder |ConvertTo-Json |Add-Content 'D:\file.json'
$data.roots.other | Get-BookmarkFolder |ConvertTo-Json |Add-Content 'D:\file.json'
$data.roots.synced | Get-BookmarkFolder |ConvertTo-Json |Add-Content 'D:\file.json'
$EndBraceClose = ']}' | Add-Content 'file.json'
Get-Content 'D:\file.json' -Raw |
ConvertFrom-Json | select -ExpandProperty markers|
Export-CSV $env:USERPROFILE\desktop\ChromeBookMarx_$isodate.csv -NoTypeInformation
# end logging
###########################
Stop-Transcript
###########################
JSON 文件的结果如下所示: -
{
"BookMarks":
[
{
"Folder": "Sanddance",
"Name": "Microsoft Garage",
"URL": "https://www.microsoft.com/en-us/garage/workbench/",
"Added": "\/Date(1504585556230)\/"
},
{
"Folder": "Sanddance",
"Name": "Microsoft has a new data visualization tool you can use for free",
"URL": "https://thenextweb.com/",
"Added": "\/Date(1504584050296)\/"
}
]
[
{
"Folder": "Amazon",
"Name": "Cycling Equipment: Buy Cycling Accessories, Bike Tools \u0026 Equipment Online at Low Prices in India",
"URL": "https://www.amazon.in/",
"Added": "\/Date(1504859500323)\/"
},
{
"Folder": "Other bookmarks",
"Name": "Zakir Khan-Fan Honge Dusron Ke Apne To Dost Hote Hai - YouTube",
"URL": "https://www.youtube.com/watch?v=n4WKiwhn29o",
"Added": "\/Date(1497416694729)\/"
}
]
]
}
第 16 行和第 17 行的括号似乎是导致问题的原因。 我需要一些帮助来纠正编写的代码。
如果你看一下 JSON 示例的基本结构,就会发现没有 [] http://json.org/example.html
所以我稍微调整了你的脚本我的 chrome 路径也与你的不同,所以你必须更改它。
$isodate = Get-Date -Format yyyymmmdd_hhmmss
$file = "C:\temp\file.json"
#Declare Variables
$pathToJsonFile = "$env:localappdata\Google\Chrome\User Data\Profile 1\Bookmarks"
#$JsonFilePath = "D:\04. PowerShell\BookMarks\ChromeBookMarx.json"
#$OutputFilePath = "D:\BookMarx.csv"
$data = Get-content $pathToJsonFile | out-string | ConvertFrom-Json
Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"
#A nested function to enumerate bookmark folders
Function Get-BookmarkFolder {
[cmdletbinding()]
Param(
[Parameter(Position=0,ValueFromPipeline=$True)]
$Node
)
Process
{
foreach ($child in $node.children)
{
#get parent folder name
$parent = $node.Name
if ($child.type -eq 'Folder')
{
Write-Verbose "Processing $($child.Name)"
Get-BookmarkFolder $child
}
else
{
$hash= [ordered]@{
Folder = $parent
Name = $child.name
URL = $child.url
Added = [datetime]::FromFileTime(([double]$child.Date_Added)*10)
}
#write custom object
New-Object -TypeName PSobject -Property $hash
} #else url
} #foreach
} #process
} #end function
#create a new JSON file
$text | Set-Content $file -Force
$test1 = '{
"markers":' | Add-Content $file
#these should be the top level "folders"
$data.roots.bookmark_bar | Get-BookmarkFolder |ConvertTo-Json |Add-Content $file
$data.roots.other | Get-BookmarkFolder |ConvertTo-Json |Add-Content $file
$data.roots.synced | Get-BookmarkFolder |ConvertTo-Json |Add-Content $file
'}' | Add-Content $file
Get-Content $file -Raw |
ConvertFrom-Json | select -ExpandProperty markers|
Export-CSV $env:USERPROFILE\desktop\ChromeBookMarx_$isodate.csv -NoTypeInformation
这会在我的桌面上提供一个可用的 CSV 文件。顺便说一句,有趣的想法。
所以这一行是我发现的最大问题:
$EndBraceClose = ']}' | Add-Content 'file.json'
$isodate = Get-Date -Format yyyymmmdd_hhmmss
$pathToJsonFile = "$env:localappdata\Google\Chrome\User Data\Default\Bookmarks"
$data = Get-content $pathToJsonFile | out-string | ConvertFrom-Json
#A nested function to enumerate bookmark folders
Function Get-BookmarkFolder {
[cmdletbinding()]
Param(
[Parameter(Position=0,ValueFromPipeline=$True)]
$Node
)
Process
{
foreach ($child in $node.children)
{
#get parent folder name
$parent = $node.Name
if ($child.type -eq 'Folder')
{
Write-Verbose "Processing $($child.Name)"
Get-BookmarkFolder $child
}
else
{
$hash= [ordered]@{
Folder = $parent
Name = $child.name
URL = $child.url
Added = [datetime]::FromFileTime(([double]$child.Date_Added)*10)
}
#write custom object
New-Object -TypeName PSobject -Property $hash
} #else url
} #foreach
} #process
} #end function
$data = Get-content $pathToJsonFile -Encoding UTF8 | out-string | ConvertFrom-Json
$sections = $data.roots.PSObject.Properties | select -ExpandProperty name
$output = ForEach ($entry in $sections) {
$data.roots.$entry | Get-BookmarkFolder
}
$output | Export-CSV $env:USERPROFILE\desktop\ChromeBookMarx_$isodate.csv -NoTypeInformation
调出一个旧的,但我是在没有临时 json 文件的情况下完成的。
不确定与此同时 ConvertTo-Json 是否有任何变化。
这是我的看法,它还输出每个书签的文件夹路径,并按照我想要的方式格式化日期时间:
#Path to chrome bookmarks
$pathToJsonFile = "$env:localappdata\Google\Chrome\User Data\Default\Bookmarks"
#Helper vars
$temp = "C:\temp\google-bookmarks.json"
$timestamp = Get-Date -Format yyyymmmdd_hhmmss
$global:bookmarks = @()
#A nested function to enumerate bookmark folders
Function Get-BookmarkFolder {
[cmdletbinding()]
Param(
[Parameter(Position=0,ValueFromPipeline=$True)]
$Node
)
Process
{
foreach ($child in $node.children)
{
#get parent folder name
$parent = $node.Name
$folder = If (!$node.Folder) {""} Else {$node.Folder}
$folder = $folder + $parent + "/"
$child | Add-Member @{Folder= $folder}
if ($child.type -eq 'Folder')
{
# Write-Verbose "Processing $($child.Name)"
Get-BookmarkFolder $child
}
else
{
$hash= [ordered]@{
Folder = $parent
Name = $child.name
URL = $child.url
Path = $child.folder.substring(0,$child.folder.Length-1)
Added = "{0:yyyyMMddHHmmssfff}" -f [datetime]::FromFileTime(([double]$child.Date_Added)*10)
}
#add ascustom object to collection
$global:bookmarks += New-Object -TypeName PSobject -Property $hash
} #else url
} #foreach
} #process
} #end function
$data = Get-content $pathToJsonFile -Encoding UTF8 | out-string | ConvertFrom-Json
#process top level "folders"
$data.roots.bookmark_bar | Get-BookmarkFolder
$data.roots.other | Get-BookmarkFolder
$data.roots.synced | Get-BookmarkFolder
#create a new JSON file
$empty | Set-Content $temp -Force
'{
"bookmarks":' | Add-Content $temp
#these should be the top level "folders"
$global:bookmarks | ConvertTo-Json | Add-Content $temp
'}' | Add-Content $temp
Write-Verbose $temp
Get-Content $temp -Raw |
ConvertFrom-Json |
select -ExpandProperty bookmarks |
Export-CSV $env:USERPROFILE\Desktop\ChromeBookmarks_$timestamp.csv -NoTypeInformation
Remove-Item $temp
请注意我如何使用全局数组首先收集所有书签,以避免任何多余的尖括号
[]
破坏了Snak3d0c的代码。
谢谢大家的意见,我学到了很多。 从 Snak3D0c 的输入中为单行语法添加了一种较短的形式:
$link=gc "$env:localappdata\Google\Chrome\User Data\Default\Bookmarks" | out-string | ConvertFrom-Json;$data.roots.bookmark_bar.children| ?{($.url -like 'http*')}| Select name,@{l="Link";e={"$($.url)"}},@{l="last accessed";e={"$([datetime]::FromFileTime(([double]$_.Date_Added)*10))"}}| epcsv .\listin_url.csv -Deli "," -NoT