Мне нужно переименовать следующие файлы, удалив все числовые цифры, связанные после первого нуля в имени файла.
Единственная часть имени файла, которую я знаю, фиксированная часть:
StT_QX10
StT_QY20
StT_QE50
StT_QG70
StT_QH90
Однако переменная часть имени файла, которая автоматически назначается сервером, генерирующим эти текстовые файлы, неизвестна для каждого дня, всегда другая и переменная часть - это
_46_9448513023277552554
_31_7886000158142287461
_55_2426936282534604666
_39_8749067416635922512
_27_2363684982157969174
Вход
StT_QX10_46_9448513023277552554.txt
StT_QY20_31_7886000158142287461.txt
StT_QE50_55_2426936282534604666.txt
StT_QG70_39_8749067416635922512.txt
StT_QH90_27_2363684982157969174.txt
Я имею в виду, что мне нужен результат, как показано ниже
Выход
StT_QX10.txt
StT_QY20.txt
StT_QE50.txt
StT_QG70.txt
StT_QH90.txt
Числовые цифры, стоящие после первой нулевой цифры имени файла, абсолютно случайны, и узнать их заранее невозможно. Но их количество всегда фиксированное, то есть сначала 2 цифры предшествуют и следуют подчеркивание, а затем 19 цифр без перерыва.
_46_9448513023277552554.txt
_31_7886000158142287461.txt
_55_2426936282534604666.txt
_39_8749067416635922512.txt
_27_2363684982157969174.txt
я застрял здесь
Set FSO = CreateObject("Scripting.FileSystemObject")
Arr = Array("StT_QX10", "StT_QY20", "StT_QE50", "StT_QG70", "StT_QH90")
For I = 0 To UBound(Arr)
If FSO.FileExists("C:\BOE\StT_" & Arr(I) & "") Then
Else
MsgBox("The file does not exist : " & vbcrlf & Now() & vbcrlf & Err.Number & vbcrlf & Err.Description)
End If
Next
Set FSO = Nothing
Ваши входные примеры легко преобразуются в желаемый результат путем обрезки последних 23 символов (не считая расширения). Действительно ли всегда нужно обрезать 23 символа?
Эту проблему можно упростить с помощью регулярных выражений для проверки и разделения имени файла на три части.
(StT_Q[EGHXY][12579]0)
(_[0-9]{2}_[0-9]{19})
(\.txt)
Как только три части будут идентифицированы, мы можем использовать его, чтобы переписать имя файла, оставив только первую и последнюю части, отбросив вторую часть.
Для этого я провел рефакторинг подпрограммы RenameIt
, которая проверяет входящие имена файлов и, если они совпадают, переименовывает файл, в противном случае оставляет его в покое. Затем у нас есть вторая подпрограмма RenameAll
, которая сканирует текущий рабочий каталог на наличие всех имен файлов и передает их первой подпрограмме.
REM Test.vbs
Sub RenameIt(filename)
Set rx = New RegExp
rx.Pattern = "^(StT_Q[EGHXY][12579]0)(_[0-9]{2}_[0-9]{19})(\.txt)$"
Set m = rx.Execute(filename)
If m.Count = 0 Then
Exit Sub
End If
a = m(0).Submatches(0)
b = m(0).Submatches(1)
c = m(0).Submatches(2)
newfilename = a + c
WScript.Echo "Rename: " + filename + " -> " + newfilename
dim fso
set fso = CreateObject("Scripting.FileSystemObject")
call fso.MoveFile(filename, newfilename)
End Sub
Sub RenameAll
Dim fso
set fso = CreateObject( "Scripting.FileSystemObject" )
set folder = fso.getFolder( "." )
set files = folder.Files
For each f in Files
Call RenameIt(f.Name)
Next
End Sub
Call RenameAll
Вот соответствующий тестовый сценарий:
DEL StT*.TXT
ECHO TEST > StT_QX10_46_9448513023277552554.txt
ECHO TEST > StT_QY20_31_7886000158142287461.txt
ECHO TEST > StT_QE50_55_2426936282534604666.txt
ECHO TEST > StT_QG70_39_8749067416635922512.txt
ECHO TEST > StT_QH90_27_2363684982157969174.txt
DIR
CSCRIPT test.vbs
DIR
Когда мы запускаем приведенное выше с помощью CScript, вы видите, что регулярное выражение используется для разбиения имени файла на 3 части: a, b, c соответственно, а затем мы отбрасываем середину, чтобы создать newfilename
.
PS C:\tmp\so> .\runtest.bat
C:\tmp\so>DEL *.TXT
C:\tmp\so>ECHO TEST 1>StT_QX10_46_9448513023277552554.txt
C:\tmp\so>ECHO TEST 1>StT_QY20_31_7886000158142287461.txt
C:\tmp\so>ECHO TEST 1>StT_QE50_55_2426936282534604666.txt
C:\tmp\so>ECHO TEST 1>StT_QG70_39_8749067416635922512.txt
C:\tmp\so>ECHO TEST 1>StT_QH90_27_2363684982157969174.txt
C:\tmp\so>DIR
Volume in drive C is OS
Volume Serial Number is A23D-E90D
Directory of C:\tmp\so
23/08/2024 08:48 AM <DIR> .
23/08/2024 08:34 AM <DIR> ..
23/08/2024 08:48 AM 286 runtest.bat
23/08/2024 08:48 AM 7 StT_QE50_55_2426936282534604666.txt
23/08/2024 08:48 AM 7 StT_QG70_39_8749067416635922512.txt
23/08/2024 08:48 AM 7 StT_QH90_27_2363684982157969174.txt
23/08/2024 08:48 AM 7 StT_QX10_46_9448513023277552554.txt
23/08/2024 08:48 AM 7 StT_QY20_31_7886000158142287461.txt
23/08/2024 08:48 AM 688 test.vbs
7 File(s) 1,009 bytes
2 Dir(s) 68,625,317,888 bytes free
C:\tmp\so>CSCRIPT test.vbs
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.
Rename: StT_QE50_55_2426936282534604666.txt -> StT_QE50.txt
Rename: StT_QG70_39_8749067416635922512.txt -> StT_QG70.txt
Rename: StT_QH90_27_2363684982157969174.txt -> StT_QH90.txt
Rename: StT_QX10_46_9448513023277552554.txt -> StT_QX10.txt
Rename: StT_QY20_31_7886000158142287461.txt -> StT_QY20.txt
C:\tmp\so>DIR
Volume in drive C is OS
Volume Serial Number is A23D-E90D
Directory of C:\tmp\so
23/08/2024 08:48 AM <DIR> .
23/08/2024 08:34 AM <DIR> ..
23/08/2024 08:48 AM 286 runtest.bat
23/08/2024 08:48 AM 7 StT_QE50.txt
23/08/2024 08:48 AM 7 StT_QG70.txt
23/08/2024 08:48 AM 7 StT_QH90.txt
23/08/2024 08:48 AM 7 StT_QX10.txt
23/08/2024 08:48 AM 7 StT_QY20.txt
23/08/2024 08:48 AM 688 test.vbs
7 File(s) 1,009 bytes
2 Dir(s) 68,625,317,888 bytes free
Большое спасибо за ответ. Но похоже это не решает мою проблему, я не знаю названия файлов, которые надо переименовывать изначально. С вашего предположения считается, что я заранее знаю имя файла...
Если нам нужно определить список файлов, вам нужно лучше объяснить это в своем вопросе.
Хорошо, готово. Я отредактировал свой первый вопрос. надеюсь, ты понимаешь
Вопрос не ясен. Это слишком открыто для субъективной интерпретации. Я сделал некоторые предположения относительно ваших требований. то есть сканирование текущей папки на наличие текстовых файлов, соответствующих определенному шаблону, а затем создание нового имени на его основе.
Option Explicit
RenameFilesByBaseName
Sub RenameFilesByBaseName()
' Define constants.
Const FOLDER_PATH = "C:\BOE\"
Const FILE_EXTENSION = "txt"
Dim NEW_BASE_NAMES: NEW_BASE_NAMES = Array( _
"StT_QX10", "StT_QY20", "StT_QE50", "StT_QG70", "StT_QH90")
' Create an instance of the FileSystemObject object.
Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
' Return all files with the specified extension in a dictionary.
Dim dict: Set dict = DictFilesInFolder(FOLDER_PATH, FILE_EXTENSION, fso)
If dict.Count = 0 Then
MsgBox "No """ & FILE_EXTENSION & """ files found in """ _
& FOLDER_PATH & """!", vbExclamation
Exit Sub
End If
' Rename the first found file (assuming only one)
' that begins with the new base name to 'the new base name'.
Dim OldName, i, NewBaseName, NewName, WasFileFound
For i = 0 To UBound(NEW_BASE_NAMES)
NewBaseName = NEW_BASE_NAMES(i)
WasFileFound = False
For Each OldName In dict.Keys
If InStr(1, OldName, NewBaseName, vbTextCompare) = 1 Then ' begins w
WasFileFound = True
Exit For
End If
Next
If WasFileFound Then
NewName = NewBaseName & "." & FILE_EXTENSION
If fso.FileExists(fso.BuildPath(FOLDER_PATH, NewName)) Then
MsgBox "The file """ & NewName & """ already exists in """ _
& FOLDER_PATH & """!", vbExclamation
Else
dict(OldName).Name = NewName
MsgBox "Renamed """ & OldName & """ to """ & NewName & """.", _
vbInformation
End If
dict.Remove OldName
Else
MsgBox "No file beginning with """ & NewBaseName & """ found!", _
vbExclamation
End If
Next
' Inform.
MsgBox "Files renamed.", vbInformation
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns a dictionary holding all files with a specific extension
' ('FileExtension') in a folder ('FolderPath') using
' the FileSystemObject object ('fso').
' The keys will hold the file names
' while the corresponding items will hold the file object.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function DictFilesInFolder(ByVal FolderPath, ByVal FileExtension, ByVal fso)
Dim dict: Set dict = CreateObject("Scripting.Dictionary")
Dim fsoFile, CurrentFileExtension
For Each fsoFile In fso.GetFolder(FolderPath).Files
CurrentFileExtension = fso.GetExtensionName(fsoFile)
If StrComp(CurrentFileExtension, FileExtension, vbTextCompare) = 0 Then
Set dict(fsoFile.Name) = fsoFile
End If
Next
Set DictFilesInFolder = dict
End Function
Если все файлы такие, как в приведенных примерах, то все, что нужно, — это обрезать последние 23 символа из базового имени файла. Если последняя часть имен файлов различается по длине, другой простой подход — разделить имя на символ подчеркивания и сохранить первые две части. Вот примеры каждого подхода:
Пример 1: обрезать последние 23 символа
folderPath = "C:\temp"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set folder = oFSO.GetFolder(folderPath)
For Each file In folder.Files
If LCase(oFSO.GetExtensionName(file.Name)) = "txt" And Left(file.Name, 4) = "StT_" And Len(file.Name) > 27 Then
BaseName = oFSO.GetBaseName(file.Name)
file.Name = Left(BaseName, Len(BaseName) - 23) & ".txt"
End If
Next
Пример 2. Разделите текст с помощью подчеркивания и сохраните первые две части.
folderPath = "C:\temp"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set folder = oFSO.GetFolder(folderPath)
For Each file In folder.Files
If LCase(oFSO.GetExtensionName(file.Name)) = "txt" And Left(file.Name, 4) = "StT_" And Len(file.Name) > 27 Then
BaseName = oFSO.GetBaseName(file.Name)
a = Split(BaseName,"_")
file.Name = a(0) & "_" & a(1) & ".txt"
End If
Next
Обязательно ли это писать по сценарию? Вы можете использовать БРУ.