更换的所有Guid在一个文件与新Guid从命令行
-
18-09-2019 - |
题
我有一个文件中包含大量出现的串 Guid="GUID HERE"
(在那里 GUID HERE
是一个独特的GUID在每次发生)我想要替换现有的GUID与一个新的独特的GUID。
这是在一个窗户开发计算机,这样我就可以产生独特的Guid与 uuidgen.exe
(其产生的GUID在stdout每次运行)。我 sed
而这样的提供(但没有 awk
奇怪的是).
我基本上是在试图找出如果这是可能的(如果可以,如何)使用的输出的命令行程序的替代案文中的一个 sed
代表达这样我可以让这个更换用最低的办法了我的一部分。我不需要使用 sed
-如果还有另一种方式做到这一点,例如一些疯狂的 vim
-fu或某些其他程序,这将工作-但是我喜欢的解决方案,利用最少的*尼克斯的节目因为我真的不对*尼克斯的机器。
到是清楚的,如果我有一个文件是这样的:
etc etc Guid="A" etc etc Guid="B"
我想它变成这样的:
etc etc Guid="C" etc etc Guid="D"
其中的A、B、C、D是实际Guid的,当然。
(例如,我看到 xargs
用于与此类似,但它没有提供的计算机上我需要这个运行。我可以安装,如果这是真的唯一方式,虽然我不想)
解决方案
我改写了C#解决方案中置。我想它会更容易让你跑一个powershell脚本,然后汇编C#exe。
步骤对使用这样的:
- 下载/安装powershell
- 保存的代码下面的某个地方,名叫GuidSwap.ps1
- 修改$filename and$outputFilename变量来满足你的需要
- 运行 powershell-noexit c:\location o\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"
其他提示
你是开放的编译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;
}
}
}
}
我一直在寻找一种方式,以取代在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)
"@
你可以捕捉到UID到一个变量,然后再做sed的?
@echo off
setlocal enabledelayedexpansion
for /f %%x in ('uuidgen.exe') do (
set uid=%%x
)
sed -e "s/Guid=\"\(.*\)\"/Guid=\"!uid!\"/g" file
我很喜欢由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>