Мне нужна помощь от гуру сценариев оболочки.
У меня есть файл .txt (журнал), который отслеживает IP-адреса клиентов в нескольких строках в формате, аналогичном этому:
Line1 - Client IP [192.168.0.1] Other data
Line2 - Client IP [192.168.0.2] Other data
Line3 - Client IP [192.168.0.3] Other data
Line4 - Client IP [192.168.0.2] Other data
Line5 - Client IP [192.168.0.1] Other data
...
Мне нужно создать скрипт, который:
В предыдущем примере получился бы файл:
192.168.0.1
192.168.0.2
192.168.0.3
Я работаю в ОС Windows, но могу использовать такие инструменты, как Cygwin или Инструменты Unix (которые предоставляют Unix-подобные команды, такие как grep, sort и т. д. Под Windows).
Решение без сценариев тоже может быть хорошим.
Заранее спасибо за помощь.





cat yourfile.txt | sed 's/*\[//g' | sed 's/\]*//g' | sort | uniq > newfile.txt
Для скобок могут быть ненужными экранирования. Не помню. Все эти инструменты должен доступны в Cygwin.
Вот короткий сценарий sed, который извлекает часть между квадратными скобками, а затем sort -u удаляет дубликаты:
sed -e 's/^.*\[\(.*\)\].*$//g' < inputfile | sort -u
В PowerShell:
Многословный путь -
$regex = '(?<IPAddress>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
get-content log.txt | where-object {if ($_ -match $regex){$matches.ipaddress}} | group-object -noelement
Укороченная версия
gc log.txt | % {if ($_ -match $regex){$matches.ipaddress}} | group -n
Довольно сложно превзойти эти сценарии sed по лаконичности. Хорошо, читабельность - проблема ...
Вы могли бы сделать более подробную и, возможно, более читаемую версию на VBScript, используя Scripting.FileSystemObject для доступа к файлам, используя регулярные выражения VBScript и объект Dictionary, как показано ниже.
Option Explicit
Dim oFSO
Dim oRgx
Dim oMatch
Dim oMatches
Dim oStream
Dim sLine
Dim oDict
Dim sIP
Dim aKeys
Dim sKey
Set oFSO = CreateObject( "Scripting.FileSystemObject" )
Set oDict = CreateObject( "Scripting.Dictionary" )
Set oStream = oFSO.OpenTextFile( "log.txt", 1, False )
Set oRgx = new regexp
oRgx.Pattern = "\[(.+?)\]"
oRgx.Global = True
Do While Not oStream.AtEndOfStream
sLine = oStream.ReadLine
Set oMatches = oRgx.Execute(sLine)
For Each omatch in omatches
sIP = oMatch.SubMatches(0)
If Not oDict.Exists( sIP ) Then
oDict.Add sIp,1
End If
Next
Loop
aKeys = oDict.Keys
For Each sKey in aKeys
wscript.echo sKey
Next
Если вы можете использовать Cygwin, нет смысла беспокоиться о решении для сценариев Windows.
Если вам нужно много писать сценарии на платформе Windows, вам следует попробовать PowerShell. Его легко освоить, и на платформе Windows с ним мало что можно сделать.