У меня есть файл, содержащий большое количество случаев строки Guid="GUID HERE"
(где GUID HERE
уникальный GUID при каждом возникновении), и я хочу заменить каждый существующий GUID новым уникальным GUID.
Это находится на машине разработки Windows, таким образом, я могу генерировать уникальные GUID с uuidgen.exe
(который производит GUID на stdout каждый раз, когда он выполняется). Я имею sed
и такое доступное (но нет awk
достаточно странно).
Я в основном пытаюсь выяснить, возможно ли (и если так, как) использовать вывод программы командной строки как текст замены в a 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.Я подумал, что вам будет проще запустить сценарий PowerShell, а затем скомпилировать C # exe.
Действия по использованию этого:
## 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"
вы можете просто захватить uid в сначала переменную, а затем выполните команду sed?
@echo off
setlocal enabledelayedexpansion
for /f %%x in ('uuidgen.exe') do (
set uid=%%x
)
sed -e "s/Guid=\"\(.*\)\"/Guid=\"!uid!\"/g" file
Не могли бы вы скомпилировать консольное приложение 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;
}
}
}
}