从命令行将文件中的所有 GUID 替换为新的 GUID

发布于 2024-08-20 10:57:08 字数 698 浏览 3 评论 0原文

我有一个文件包含大量出现的字符串 Guid="GUID HERE" (其中 GUID HERE 是每次出现的唯一 GUID),我想替换每个现有的 GUID 都有一个新的唯一 GUID。

这是在 Windows 开发计算机上,因此我可以使用 uuidgen.exe 生成唯一的 GUID(每次运行时都会在 stdout 上生成 GUID)。我有 sed 等可用的东西(但奇怪的是没有 awk )。

我基本上想弄清楚是否可以(如果可以,如何)使用命令行程序的输出作为 sed 替换表达式中的替换文本,以便我可以这样做我只需付出最少的努力即可进行更换。我不需要使用 sed - 如果有其他方法可以做到这一点,例如一些疯狂的 vim -fu 或其他程序,那也可以 - - 但我更喜欢使用最少的 *nix 程序集的解决方案,因为我并不真正使用 *nix 机器。

需要明确的是,如果我有一个这样的文件:

etc etc Guid="A" etc etc Guid="B"

我希望它变成这样:

etc etc Guid="C" etc etc Guid="D"

其中 A、B、C、D 当然是实际的 GUID。

(例如,我见过 xargs 用于类似的事情,但它在我需要运行它的机器上也不可用。如果它确实是唯一的方法,我可以安装它,尽管我宁愿不)

I have a file containing a large number of occurrences of the string Guid="GUID HERE" (where GUID HERE is a unique GUID at each occurrence) and I want to replace every existing GUID with a new unique GUID.

This is on a Windows development machine, so I can generate unique GUIDs with uuidgen.exe (which produces a GUID on stdout every time it is run). I have sed and such available (but no awk oddly enough).

I am basically trying to figure out if it is possible (and if so, how) to use the output of a command-line program as the replacement text in a sed substitution expression so that I can make this replacement with a minimum of effort on my part. I don't need to use sed -- if there's another way to do it, such as some crazy vim-fu or some other program, that would work as well -- but I'd prefer solutions that utilize a minimal set of *nix programs since I'm not really on *nix machines.

To be clear, if I have a file like this:

etc etc Guid="A" etc etc Guid="B"

I would like it to become this:

etc etc Guid="C" etc etc Guid="D"

where A, B, C, D are actual GUIDs, of course.

(for example, I have seen xargs used for things similar to this, but it's not available on the machines I need this to run on, either. I could install it if it's really the only way, although I'd rather not)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

灰色世界里的红玫瑰 2024-08-27 10:57:08

我在 PowerShell 中重写了 C# 解决方案。我认为运行 powershell 脚本然后编译 C# exe 会更容易。

使用步骤:

  1. 下载/安装 powershell
  2. 将下面的代码保存在某个位置,命名为 GuidSwap.ps1
  3. 修改 $filename 和 $outputFilename 变量以满足您的需要
  4. 运行 powershell -noexit c:\location\to\guidswap.ps1

## GuidSwap.ps1
##
## Reads a file, finds any GUIDs in the file, and swaps them for a NewGUID
##

$filename = "d:\test.txt"
$outputFilename = "d:\test_new.txt"

$text = [string]::join([environment]::newline, (get-content -path $filename))

$sbNew = new-object system.text.stringBuilder

$pattern = "[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}"

$lastStart = 0
$null = ([regex]::matches($text, $pattern) | %{
    $sbNew.Append($text.Substring($lastStart, $_.Index - $lastStart))
    $guid = [system.guid]::newguid()
    $sbNew.Append($guid)
    $lastStart = $_.Index + $_.Length
})
$null = $sbNew.Append($text.Substring($lastStart))

$sbNew.ToString() | out-file -encoding ASCII $outputFilename

Write-Output "Done"

I rewrote the C# solution in PowerShell. I figured it would be easier for you to run a powershell script then compile a C# exe.

Steps for using this:

  1. Download/install powershell
  2. Save the code below somewhere, named GuidSwap.ps1
  3. Modify the $filename and $outputFilename variables to suit your needs
  4. Run powershell -noexit c:\location\to\guidswap.ps1

## GuidSwap.ps1
##
## Reads a file, finds any GUIDs in the file, and swaps them for a NewGUID
##

$filename = "d:\test.txt"
$outputFilename = "d:\test_new.txt"

$text = [string]::join([environment]::newline, (get-content -path $filename))

$sbNew = new-object system.text.stringBuilder

$pattern = "[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}"

$lastStart = 0
$null = ([regex]::matches($text, $pattern) | %{
    $sbNew.Append($text.Substring($lastStart, $_.Index - $lastStart))
    $guid = [system.guid]::newguid()
    $sbNew.Append($guid)
    $lastStart = $_.Index + $_.Length
})
$null = $sbNew.Append($text.Substring($lastStart))

$sbNew.ToString() | out-file -encoding ASCII $outputFilename

Write-Output "Done"
败给现实 2024-08-27 10:57:08

我一直在寻找一种方法来替换 Visual Studio 解决方案中的所有 GUID,因此我获取了 StackOverflow 问题 (GuidSwap.ps1) 的答案并对其进行了扩展,以便脚本跟踪跨多个文件引用的 GUID。下面的标题中显示了一个示例。

<#
    .Synopsis
    Replace all GUIDs in specified files under a root folder, carefully keeping track 
    of how GUIDs are referenced in different files (e.g. Visual Studio solution).

    Loosely based on GuidSwap.ps1:
    http://stackoverflow.com/questions/2201740/replacing-all-guids-in-a-file-with-new-guids-from-the-command-line

    .NOTES
    Version:        1.0
    Author:         Joe Zamora (blog.idmware.com)
    Creation Date:  2016-03-01
    Purpose/Change: Initial script development

    .EXAMPLE
    .\ReplaceGuids.ps1 "C:\Code\IDMware" -FileNamePatterns @("*.sln","*.csproj","*.cs") -Verbose -WhatIf
#>

# Add common parameters to the script.
[CmdletBinding()]
param(
    $RootFolder
    ,$LogFolder='.'
    ,[String[]]$FileNamePatterns
    ,[switch]$WhatIf
)
$global:WhatIf = $WhatIf.IsPresent

# Change directory to the location of this script.
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
cd $dir
$ScriptName = $MyInvocation.MyCommand.Name

If(!($RootFolder))
{
    Write-Host @"
Usage: $ScriptName  -RootFolder <RootFolder> [Options]

Options:
    -LogFolder <LogFolder>                      Defaults to location of script.

    -FileNamePatterns @(*.ext1, *.ext2, ...)    Defaults to all files (*).

    -WhatIf                                     Test run without replacements.

    -Verbose                                    Standard Powershell flags.
    -Debug
"@
    Exit
}

if ($LogFolder -and !(Test-Path "$LogFolder" -PathType Container))
{
    Write-Host "No such folder: '$LogFolder'"
    Exit
}

<#
    .Synopsis
    This code snippet gets all the files in $Path that contain the specified pattern.
    Based on this sample:
    http://www.adminarsenal.com/admin-arsenal-blog/powershell-searching-through-files-for-matching-strings/
#>
function Enumerate-FilesContainingPattern {
[CmdletBinding()]
param(
    $Path=(throw 'Path cannot be empty.')
    ,$Pattern=(throw 'Pattern cannot be empty.')
    ,[String[]]$FileNamePatterns=$null
)
    $PathArray = @()
    if (!$FileNamePatterns) {
        $FileNamePatterns = @("*")
    }

    ForEach ($FileNamePattern in $FileNamePatterns) {
        Get-ChildItem $Path -Recurse -Filter $FileNamePattern |
        Where-Object { $_.Attributes -ne "Directory"} |
        ForEach-Object {
            If (Get-Content $_.FullName | Select-String -Pattern $Pattern) {
                $PathArray += $_.FullName
            }
        }
    }
    $PathArray
} <# function Enumerate-FilesContainingPattern #>

# Timestamps and performance.
$stopWatch = [System.Diagnostics.Stopwatch]::StartNew()
$startTime = Get-Date
Write-Verbose @"

--- SCRIPT BEGIN $ScriptName $startTime ---

"@

# Begin by finding all files under the root folder that contain a GUID pattern.
$GuidRegexPattern = "[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}"
$FileList = Enumerate-FilesContainingPattern $RootFolder $GuidRegexPattern $FileNamePatterns

$LogFilePrefix = "{0}-{1}" -f $ScriptName, $startTime.ToString("yyyy-MM-dd_HH-mm-ss")
$FileListLogFile = Join-Path $LogFolder "$LogFilePrefix-FileList.txt"
$FileList | ForEach-Object {$_ | Out-File $FileListLogFile -Append}
Write-Host "File list log file:`r`n$FileListLogFile"
cat $FileListLogFile | %{Write-Verbose $_}

# Next, do a read-only loop over the files and build a mapping table of old to new GUIDs.
$guidMap = @{}
foreach ($filePath in $FileList)
{
    $text = [string]::join([environment]::newline, (get-content -path $filePath))
    Foreach ($match in [regex]::matches($text, $GuidRegexPattern)) {
        $oldGuid = $match.Value.ToUpper()
        if (!$guidMap.ContainsKey($oldGuid)) {
            $newGuid = [System.Guid]::newguid().ToString().ToUpper()
            $guidMap[$oldGuid] = $newGuid
        }
    }
}

$GuidMapLogFile = Join-Path $LogFolder "$LogFilePrefix-GuidMap.csv"
"OldGuid,NewGuid" | Out-File $GuidMapLogFile
$guidMap.Keys | % { "$_,$($guidMap[$_])" | Out-File $GuidMapLogFile -Append }
Write-Host "GUID map log file:`r`n$GuidMapLogFile"
cat $GuidMapLogFile | %{Write-Verbose $_}

# Finally, do the search-and-replace.
foreach ($filePath in $FileList) {
    Write-Verbose "Processing $filePath"
    $newText = New-Object System.Text.StringBuilder
    cat $filePath | % { 
        $original = $_
        $new = $_
        $isMatch = $false
        $matches = [regex]::Matches($new, $GuidRegexPattern)
        foreach ($match in $matches) {
            $isMatch = $true
            $new = $new -ireplace $match.Value, $guidMap[$match.Value.ToString().ToUpper()]
        }        
        $newText.AppendLine($new) | Out-Null
        if ($isMatch) {
            $msg = "Old: $original`r`nNew: $new"
            if ($global:WhatIf) {
                Write-Host "What if:`r`n$msg"
            } else {
                Write-Verbose "`r`n$msg"
            }
        }
    }
    if (!$global:WhatIf) {
        $newText.ToString() | Set-Content $filePath
    }
}

# Timestamps and performance.
$endTime = Get-Date
Write-Verbose @"

--- SCRIPT END $ScriptName $endTime ---

Total elapsed: $($stopWatch.Elapsed)
"@

I was looking for a way to replace all GUIDs in a Visual Studio solution, so I took the answer to this StackOverflow question (GuidSwap.ps1) and extended it so that the script keeps track of GUIDs that are referenced across multiple files. An example is shown in the header below.

<#
    .Synopsis
    Replace all GUIDs in specified files under a root folder, carefully keeping track 
    of how GUIDs are referenced in different files (e.g. Visual Studio solution).

    Loosely based on GuidSwap.ps1:
    http://stackoverflow.com/questions/2201740/replacing-all-guids-in-a-file-with-new-guids-from-the-command-line

    .NOTES
    Version:        1.0
    Author:         Joe Zamora (blog.idmware.com)
    Creation Date:  2016-03-01
    Purpose/Change: Initial script development

    .EXAMPLE
    .\ReplaceGuids.ps1 "C:\Code\IDMware" -FileNamePatterns @("*.sln","*.csproj","*.cs") -Verbose -WhatIf
#>

# Add common parameters to the script.
[CmdletBinding()]
param(
    $RootFolder
    ,$LogFolder='.'
    ,[String[]]$FileNamePatterns
    ,[switch]$WhatIf
)
$global:WhatIf = $WhatIf.IsPresent

# Change directory to the location of this script.
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
cd $dir
$ScriptName = $MyInvocation.MyCommand.Name

If(!($RootFolder))
{
    Write-Host @"
Usage: $ScriptName  -RootFolder <RootFolder> [Options]

Options:
    -LogFolder <LogFolder>                      Defaults to location of script.

    -FileNamePatterns @(*.ext1, *.ext2, ...)    Defaults to all files (*).

    -WhatIf                                     Test run without replacements.

    -Verbose                                    Standard Powershell flags.
    -Debug
"@
    Exit
}

if ($LogFolder -and !(Test-Path "$LogFolder" -PathType Container))
{
    Write-Host "No such folder: '$LogFolder'"
    Exit
}

<#
    .Synopsis
    This code snippet gets all the files in $Path that contain the specified pattern.
    Based on this sample:
    http://www.adminarsenal.com/admin-arsenal-blog/powershell-searching-through-files-for-matching-strings/
#>
function Enumerate-FilesContainingPattern {
[CmdletBinding()]
param(
    $Path=(throw 'Path cannot be empty.')
    ,$Pattern=(throw 'Pattern cannot be empty.')
    ,[String[]]$FileNamePatterns=$null
)
    $PathArray = @()
    if (!$FileNamePatterns) {
        $FileNamePatterns = @("*")
    }

    ForEach ($FileNamePattern in $FileNamePatterns) {
        Get-ChildItem $Path -Recurse -Filter $FileNamePattern |
        Where-Object { $_.Attributes -ne "Directory"} |
        ForEach-Object {
            If (Get-Content $_.FullName | Select-String -Pattern $Pattern) {
                $PathArray += $_.FullName
            }
        }
    }
    $PathArray
} <# function Enumerate-FilesContainingPattern #>

# Timestamps and performance.
$stopWatch = [System.Diagnostics.Stopwatch]::StartNew()
$startTime = Get-Date
Write-Verbose @"

--- SCRIPT BEGIN $ScriptName $startTime ---

"@

# Begin by finding all files under the root folder that contain a GUID pattern.
$GuidRegexPattern = "[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}"
$FileList = Enumerate-FilesContainingPattern $RootFolder $GuidRegexPattern $FileNamePatterns

$LogFilePrefix = "{0}-{1}" -f $ScriptName, $startTime.ToString("yyyy-MM-dd_HH-mm-ss")
$FileListLogFile = Join-Path $LogFolder "$LogFilePrefix-FileList.txt"
$FileList | ForEach-Object {$_ | Out-File $FileListLogFile -Append}
Write-Host "File list log file:`r`n$FileListLogFile"
cat $FileListLogFile | %{Write-Verbose $_}

# Next, do a read-only loop over the files and build a mapping table of old to new GUIDs.
$guidMap = @{}
foreach ($filePath in $FileList)
{
    $text = [string]::join([environment]::newline, (get-content -path $filePath))
    Foreach ($match in [regex]::matches($text, $GuidRegexPattern)) {
        $oldGuid = $match.Value.ToUpper()
        if (!$guidMap.ContainsKey($oldGuid)) {
            $newGuid = [System.Guid]::newguid().ToString().ToUpper()
            $guidMap[$oldGuid] = $newGuid
        }
    }
}

$GuidMapLogFile = Join-Path $LogFolder "$LogFilePrefix-GuidMap.csv"
"OldGuid,NewGuid" | Out-File $GuidMapLogFile
$guidMap.Keys | % { "$_,$($guidMap[$_])" | Out-File $GuidMapLogFile -Append }
Write-Host "GUID map log file:`r`n$GuidMapLogFile"
cat $GuidMapLogFile | %{Write-Verbose $_}

# Finally, do the search-and-replace.
foreach ($filePath in $FileList) {
    Write-Verbose "Processing $filePath"
    $newText = New-Object System.Text.StringBuilder
    cat $filePath | % { 
        $original = $_
        $new = $_
        $isMatch = $false
        $matches = [regex]::Matches($new, $GuidRegexPattern)
        foreach ($match in $matches) {
            $isMatch = $true
            $new = $new -ireplace $match.Value, $guidMap[$match.Value.ToString().ToUpper()]
        }        
        $newText.AppendLine($new) | Out-Null
        if ($isMatch) {
            $msg = "Old: $original`r`nNew: $new"
            if ($global:WhatIf) {
                Write-Host "What if:`r`n$msg"
            } else {
                Write-Verbose "`r`n$msg"
            }
        }
    }
    if (!$global:WhatIf) {
        $newText.ToString() | Set-Content $filePath
    }
}

# Timestamps and performance.
$endTime = Get-Date
Write-Verbose @"

--- SCRIPT END $ScriptName $endTime ---

Total elapsed: $($stopWatch.Elapsed)
"@
渔村楼浪 2024-08-27 10:57:08

您愿意编译一个 C# 控制台应用程序来执行此操作吗?我很快就把这个搞定了。它将文件名作为命令行参数,查找任何看起来像 GUID 的内容,将其替换为新的 GUID,然后写入文件的新内容。

看一下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace GUIDSwap
{
    class Program
    {
        static int Main(string[] args)
        {
            try
            {
                if (args.Length == 0) throw new ApplicationException("No filename specified");

                string filename = args[0];
                filename = filename.TrimStart(new char[] { '"' }).TrimEnd(new char[] { '"' });

                if (!File.Exists(filename)) throw new ApplicationException("File not found");

                StreamReader sr = new StreamReader(filename);
                string text = sr.ReadToEnd();
                sr.Close();

                StringBuilder sbNew = new StringBuilder();

                string pattern = "[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}";

                int lastStart = 0;
                foreach (Match m in Regex.Matches(text, pattern))
                {
                    sbNew.Append(text.Substring(lastStart, m.Index - lastStart));
                    sbNew.Append(Guid.NewGuid().ToString());
                    lastStart = m.Index + m.Length;
                }

                sbNew.Append(text.Substring(lastStart));

                StreamWriter sw = new StreamWriter(filename, false);
                sw.Write(sbNew.ToString());
                sw.Flush();
                sw.Close();

                return 0;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return 1;
            }
        }
    }
}

Would you be open to compiling a C# console app to do this? I whipped this up real quick. It takes a filename as a command line argument, finds anything that looks like a GUID, replaces it with a new GUID, and writes the new contents of the file.

Take a look:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace GUIDSwap
{
    class Program
    {
        static int Main(string[] args)
        {
            try
            {
                if (args.Length == 0) throw new ApplicationException("No filename specified");

                string filename = args[0];
                filename = filename.TrimStart(new char[] { '"' }).TrimEnd(new char[] { '"' });

                if (!File.Exists(filename)) throw new ApplicationException("File not found");

                StreamReader sr = new StreamReader(filename);
                string text = sr.ReadToEnd();
                sr.Close();

                StringBuilder sbNew = new StringBuilder();

                string pattern = "[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}";

                int lastStart = 0;
                foreach (Match m in Regex.Matches(text, pattern))
                {
                    sbNew.Append(text.Substring(lastStart, m.Index - lastStart));
                    sbNew.Append(Guid.NewGuid().ToString());
                    lastStart = m.Index + m.Length;
                }

                sbNew.Append(text.Substring(lastStart));

                StreamWriter sw = new StreamWriter(filename, false);
                sw.Write(sbNew.ToString());
                sw.Flush();
                sw.Close();

                return 0;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return 1;
            }
        }
    }
}
梦里兽 2024-08-27 10:57:08

您可以先将 uid 捕获到变量中,然后再执行 sed 吗?

@echo off
setlocal enabledelayedexpansion
for /f %%x in ('uuidgen.exe') do (
        set uid=%%x
)
sed -e "s/Guid=\"\(.*\)\"/Guid=\"!uid!\"/g" file

you can just capture the uid into a variable first, then do the sed?

@echo off
setlocal enabledelayedexpansion
for /f %%x in ('uuidgen.exe') do (
        set uid=%%x
)
sed -e "s/Guid=\"\(.*\)\"/Guid=\"!uid!\"/g" file
为人所爱 2024-08-27 10:57:08

我真的很喜欢 BigJoe714 的解决方案。我进一步查找所有特定的扩展文件并替换所有 GUID。

<pre>
<code>
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace AllGuidSwap
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (args.Length == 0) throw new ApplicationException("No filename specified");

                string directory = args[0]; //Path
                string extensionToFind = args[1]; //Extension to find

                if (!Directory.Exists(directory)) throw new ApplicationException("directory not found");

                var allFiles = Directory.GetFiles(directory).Where(a => a.EndsWith(extensionToFind));

                foreach (var filename in allFiles)
                {
                    if (!File.Exists(filename)) throw new ApplicationException("File not found");

                    var sr = new StreamReader(filename);
                    var text = sr.ReadToEnd();
                    sr.Close();

                    var sbNew = new StringBuilder();

                    var pattern = "[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}";

                    var lastStart = 0;
                    foreach (Match m in Regex.Matches(text, pattern))
                    {
                        sbNew.Append(text.Substring(lastStart, m.Index - lastStart));
                        sbNew.Append(Guid.NewGuid().ToString().ToUpperInvariant());
                        lastStart = m.Index + m.Length;
                    }

                    sbNew.Append(text.Substring(lastStart));

                    var sw = new StreamWriter(filename, false);
                    sw.Write(sbNew.ToString());
                    sw.Flush();
                    sw.Close();
                }

                Console.WriteLine("Successful");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.ReadKey();
        }
    }
}

</code>
</pre>

I really like the solution by BigJoe714. I took it one step further finding all specific extension files and replace all GUIDs.

<pre>
<code>
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace AllGuidSwap
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (args.Length == 0) throw new ApplicationException("No filename specified");

                string directory = args[0]; //Path
                string extensionToFind = args[1]; //Extension to find

                if (!Directory.Exists(directory)) throw new ApplicationException("directory not found");

                var allFiles = Directory.GetFiles(directory).Where(a => a.EndsWith(extensionToFind));

                foreach (var filename in allFiles)
                {
                    if (!File.Exists(filename)) throw new ApplicationException("File not found");

                    var sr = new StreamReader(filename);
                    var text = sr.ReadToEnd();
                    sr.Close();

                    var sbNew = new StringBuilder();

                    var pattern = "[a-fA-F0-9]{8}-([a-fA-F0-9]{4}-){3}[a-fA-F0-9]{12}";

                    var lastStart = 0;
                    foreach (Match m in Regex.Matches(text, pattern))
                    {
                        sbNew.Append(text.Substring(lastStart, m.Index - lastStart));
                        sbNew.Append(Guid.NewGuid().ToString().ToUpperInvariant());
                        lastStart = m.Index + m.Length;
                    }

                    sbNew.Append(text.Substring(lastStart));

                    var sw = new StreamWriter(filename, false);
                    sw.Write(sbNew.ToString());
                    sw.Flush();
                    sw.Close();
                }

                Console.WriteLine("Successful");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.ReadKey();
        }
    }
}

</code>
</pre>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文