Получите имена файлов FSO с переименованием имен файлов для получения определенной структуры имен с помощью VBScript

Мне нужно переименовать следующие файлы, удалив все числовые цифры, связанные после первого нуля в имени файла.

Единственная часть имени файла, которую я знаю, фиксированная часть:

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   

Обязательно ли это писать по сценарию? Вы можете использовать БРУ.

LesFerch 22.08.2024 22:50

Ваши входные примеры легко преобразуются в желаемый результат путем обрезки последних 23 символов (не считая расширения). Действительно ли всегда нужно обрезать 23 символа?

LesFerch 22.08.2024 23:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
56
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Эту проблему можно упростить с помощью регулярных выражений для проверки и разделения имени файла на три части.

  • 1-я часть: (StT_Q[EGHXY][12579]0)
  • 2-я часть: (_[0-9]{2}_[0-9]{19})
  • 3-я часть: (\.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

Большое спасибо за ответ. Но похоже это не решает мою проблему, я не знаю названия файлов, которые надо переименовывать изначально. С вашего предположения считается, что я заранее знаю имя файла...

Hamamelis 22.08.2024 11:49

Если нам нужно определить список файлов, вам нужно лучше объяснить это в своем вопросе.

Stephen Quan 22.08.2024 12:39

Хорошо, готово. Я отредактировал свой первый вопрос. надеюсь, ты понимаешь

Hamamelis 22.08.2024 14:34

Вопрос не ясен. Это слишком открыто для субъективной интерпретации. Я сделал некоторые предположения относительно ваших требований. то есть сканирование текущей папки на наличие текстовых файлов, соответствующих определенному шаблону, а затем создание нового имени на его основе.

Stephen Quan 23.08.2024 00:52

Переименование файлов по базовому имени

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

Другие вопросы по теме