vbscript_Windows系统管理员的VBScript-第3部分

vbscript

Welcome, welcome!  If you are new to the series and haven't been following along, please take a brief moment to review the first three installments:

欢迎欢迎! 如果您是本系列的新手,并且还没有关注,请花一点时间回顾一下前三期:

Part 1 第1部分 Part 2 第2部分 The Missing Prequel 失踪前传

Ok, so now that we are all up to speed and on the same page, let's get on with the learnin', shall we?  This article will focus on manipulating the Windows filesystem using the VBS FileSystemObject.   Why do we want to do this?  Well, as I'm sure you know, lots of times users need things done on file servers, or you need to create home directories for new users, or copy base profiles, all sorts of stuff.  If you get it all into one script, it saves lots of time in the long run.  So, to get at the filesystem:

好吧,现在我们都快步入了同一个页面,让我们继续学习吧? 本文将重点介绍使用VBS FileSystemObject操纵Windows文件系统。 我们为什么要这样做? 好吧,正如我确定的那样,很多时候用户需要在文件服务器上完成操作,或者需要为新用户创建主目录或复制基本配置文件等各种内容。 如果将所有内容整合到一个脚本中,从长远来看,它可以节省大量时间。 因此,要获取文件系统:

Set oFS = CreateObject("Scripting.FileSystemObject")

So, now we have a handle that we can use to access the filesystem - oFS.  What can we do with it?

因此,现在有了一个可用于访问文件系统的句柄-oFS。 我们该怎么办?

Set oFS = CreateObject("Scripting.FileSystemObject")
Set oFile = oFS.CreateTextFile("c:\myfile.txt")
oFile.Writeline("Hello")
oFile.Close

If you run that, you'll get a text file created in the root of your C: drive called myfile.txt, and it will contain one line that says

如果运行该程序,您将在C:驱动器的根目录中创建一个名为myfile.txt的文本文件,该文件将包含一行内容:

Hello

你好

Easy, huh?  This is useful for when you are debugging applications that have a LOT of data in them (like arrays of over 1000 objects), and echoing all of that data to the screen simply isn't practical.  Why do I say that this is only useful for debugging?  Well, the CreateTextFile method will overwrite any text file that is there, so you'll have a fresh one every time, with only the data from the last run.  If you wanted to append to a text file, then we can use another filesystem method, FileExists:

容易吧? 当您调试其中包含很多数据的应用程序(例如,包含1000个对象的数组)并且将所有这些数据回显到屏幕上根本不切实际时,这很有用。 为什么我说这仅对调试有用? 好了,CreateTextFile方法将覆盖那里的任何文本文件,因此您每次都会得到一个新的文件,仅包含上一次运行的数据。 如果要附加到文本文件,则可以使用另一个文件系统方法FileExists:

Set oFS = CreateObject("Scripting.FileSystemObject")
If oFS.FileExists("c:\myfile.txt") Then
    Set oFile = oFS.OpenTextFile("c:\myfile.txt", 8)
Else
    Set oFile = oFS.CreateTextFile("c:\myfile.txt")
End If
oFile.Writeline("Hello")
oFile.Close

That will check to see if the file exists, and if the file does not exist, then it will create it and allow you to write to it;  if it does exist, it will open it and begin appending data at the end of the file, as opposed to completely overwriting the file (the 8 in the OpenTextFile function in line 3 indicates "ForAppending").  This is useful for logging for automated processes.  Now, what if we want to have a different log file every day?  We can use the built-in date functions to get that information for us and create the filenames on the fly.

这将检查文件是否存在,如果文件不存在,它将创建该文件并允许您对其进行写入。 如果它确实存在,它将打开它并开始在文件末尾添加数据,而不是完全覆盖该文件(第3行的OpenTextFile函数中的8表示“ ForAppending”)。 这对于记录自动化过程很有用。 现在,如果我们希望每天都有一个不同的日志文件怎么办? 我们可以使用内置的日期函数为我们获取该信息并即时创建文件名。

Set oFS = CreateObject("Scripting.FileSystemObject")
mo = Month(Now)
da = Day(Now)
yr = Year(Now)
filename = CStr(yr) & CStr(mo) & CStr(da)
If oFS.FileExists(filename) Then
    Set oFile = oFS.OpenTextFile(filename, 8)
Else
    Set oFile = oFS.CreateTextFile(filename)
End If
oFile.Writeline("Hello")
oFile.Close

And there you have it.  Every time you run this piece of code, it will check today's date, and look for a file with that name.  If it exists, it will append text to the end of it.  If it does not exist, it will create it.  How did we get the date?  Well,     Now     is a reserved word, a function that returns  the date and time right now.  Year returns only the year, Month returns only the month, Day returns only the day,  Hour would return only the hour, Minute would return only the current minute.  So, if you open your IDE and run this single line of code:

那里有。 每次您运行这段代码时,它都会检查今天的日期,并查找具有该名称的文件。 如果存在,它将在其末尾附加文本。 如果不存在,它将创建它。 我们如何获得日期? 好吧,Now是一个保留字,该函数立即返回日期和时间。 年仅返回年,月仅返回月,日仅返回日,小时仅返回小时,分钟仅返回当前分钟。 因此,如果您打开IDE并运行以下单行代码:

WScript.Echo(Now)

the output you get will be the date and time that you run it, and it will be localized (different countries display the month/day in different orders, some use a / to separate, some a -, etc).  The problem with this, as far as file system organization, is that it is not all two digit, so when you go to sort, it might be out of order.  For example, if we go YearMonthDay.txt, you might have a group of files that look like this:

得到的输出将是运行它的日期和时间,并且将进行本地化(不同的国家/地区以不同的顺序显示月/日,有些使用/分隔,有些使用-等等)。 就文件系统组织而言,这样做的问题在于它不是两位数,所以当您进行排序时,它可能会出现故障。 例如,如果我们转到YearMonthDay.txt,则可能会有一组如下所示的文件:

201011

201011

2010110

2010110

2010111

2010111

...

...

201012

201012

2010120

2010120

2010121

2010121

...

...

201013

201013

2010130

2010130

2010131

2010131

201014

201014

201015

201015

We'd rather that the filenames were a unform size.  So how do we fix this?  Well, when we created our filename, we should have inserted extra zeros.  This could be done like this:

我们希望文件名的格式不正确。 那么我们该如何解决呢? 好吧,当我们创建文件名时,我们应该插入额外的零。 可以这样完成:

filename = CStr(year(Now))
If mo < 10 Then
    filename = filename & "0" & CStr(mo)
Else
    filename = filename & CStr(mo)
End If
If da < 10 Then
    filename = filename & "0" & CStr(da)
Else
    filename = filename & CStr(da)
End If

That would get you a 4 digit year followed by a two digit month and a two digit day.  But, there is a much easier way.  We can use the string function Right, like so:

那将使您获得4位数字的年份,然后是两位数的月份和两位数的日期。 但是,有一种更简单的方法。 我们可以使用字符串函数Right,如下所示:

filename = CStr(Year(Now)) & Right("0" & CStr(Month(Now)),2) & Right("0" & CStr(Day(Now)),2)

The code above does essentially this:  filename is set to the year, then the month is retreived, and is added to a 0.  So, if it is January, the month would be 01.  If it is December, the month would be 012.  But, since we only want a 2-digit month, we take the Right(string,2) of it - the "2" in the expression says take the right-most two characters.  So  01 becomes 01, and 012 becomes 12.  Same principle for the day.  Another thing to note:  the  "&"   character is the string concatenation character.  This takes two strings, and just shoves them together.  So, if we had

上面的代码基本上是这样的:将文件名设置为年份,然后检索月份,并将其添加为0。因此,如果是1月,则月份为01。如果是12月,则月份为012。但是,由于我们只希望使用两位数的月份,因此我们采用月份的Right(string,2)-表达式中的“ 2”表示采用最右边的两个字符。 因此01变为01,012变为12。 要注意的另一件事:“&”字符是字符串连接字符。 这需要两个字符串,并将它们推在一起。 所以,如果我们有

h = "hello"
w = "world"
q = h & w
WScript.Echo(q)

The output would be:             helloworld               There wouldn't be a space.  If you want a space, you put put the space in there.

输出为:helloworld不会有空格。 如果需要空间,可以在其中放置空间。

h = "hello"
w = "world"
q = h & " " & w
WScript.Echo(q)

Now the output would be             hello world                      because we inserted the space.  

现在输出将是hello world,因为我们插入了空格。

Ok, so back to our filesystem:  The same thing can be done with folders as with files.  For example, say that you wanted each of your log files arranged in a folder hierarchy like this:

好的,回到我们的文件系统:文件夹和文件可以完成相同的操作。 例如,假设您希望每个日志文件都按照如下所示的文件夹层次结构排列:

Year  (folder)

年(文件夹)

--Month  (folder)

-月(文件夹)

----Log Files  (text files)

----日志文件(文本文件)

No problem!

没问题!

Set oFS = CreateObject("Scripting.FileSystemObject")
yr = CStr(Year(Now))
mo = Right("0" & CStr(Month(Now)),2)
da = Right("0" & CStr(Day(Now)),2)
YearFolder = "C:\" & yr
If Not oFS.FolderExists(YearFolder) Then oFS.CreateFolder(YearFolder)
MonthFolder = YearFolder & "\" & mo
If Not oFS.FolderExists(MonthFolder) Then oFS.CreateFolder(MonthFolder)
FileName = MonthFolder & "\" & yr &mo & da & ".txt"
If oFS.FileExists(FileName) Then
    Set oFile = oFS.OpenTextFile(FileName,8)
Else
    Set oFile = oFS.CreateTextFile(Filename)
End If
oFile.Writeline("Hello!")
oFile.Close

As mentioned previously, the 8 used in the OpenTextFile method causes output to be appended to the existing file.  If you want to open a text file for reading ONLY, then you would use a  "1" there, like this:

如前所述,OpenTextFile方法中使用的8导致输出附加到现有文件。 如果您想打开一个文本文件以仅读取,则可以在其中使用“ 1”,如下所示:

Set oFS = CreateObject("Scripting.FileSystemObject")
Set oFile = oFS.OpenTextFile("c:\myfile.txt",1)
data = oFile.Readline
oFile.Close

Now, the file is safe.  It is opened in read-only mode, so no data can be accidentally changed.  Also, this introduces the Readline method of the FileSystemObject object.  That will read to the next  vbCrLf(CarriageReturnLineFeed).   vbCrLf is a reserved word, and can be used at any point in string concatenation to go to the next line.  For example, if you had a very long string that you wanted to echo, instead of it opening a messagebox that would display across the entire monitor, you could break it up with vbCrLf, like this:

现在,该文件是安全的。 它以只读模式打开,因此不会意外更改任何数据。 同样,这引入了FileSystemObject对象的Readline方法。 这将读取到下一个vbCrLf(CarriageReturnLineF eed)。 vbCrLf是保留字,可以在字符串连接中的任何点使用以转到下一行。 例如,如果您有一个很长的字符串想要回显,而不是打开一个会在整个监视器上显示的消息框,则可以使用vbCrLf将其拆分,如下所示:

data = "something something something" & vbCrLf & "something something something" & vbCrLf & "something something something"
WScript.Echo(data)

That will display on three separate lines.  It's much easier to read.  About inserting vbCrLf - the Writeline method will do that for you automatically at the end of the string you pass in.  If you would prefer manual control over placement of line breaks, you can simply use the  Write method, and you will need to insert your own line breaks then.

这将显示在三行中。 它更容易阅读。 关于插入vbCrLf-Writeline方法将在您传递的字符串的末尾自动为您完成此操作。如果您希望手动控制换行符的位置,则可以简单地使用Write方法,并且需要插入然后自己换行。

Another useful string method is  Split   This is useful when you are reading from files that contain records, such as CSV files.  Some files use pipes ( | ) for delimiters, some will use other characters, but record layouts always have some type of delimiter to separate the fields.  How can we handle that?

另一个有用的字符串方法是Split(拆分)。当您从包含记录的文件(例如CSV文件)中读取时,此方法很有用。 有些文件使用竖线(|)作为分隔符,有些文件将使用其他字符,但是记录布局始终具有某种分隔符来分隔字段。 我们该如何处理?

Set oFS = CreateObject("Scripting.FileSystemObject")
Set oFile = oFS.OpenTextFile("c:\MyFile.CSV",1)
data = oFile.Readline
fields = Split(data,",")
oFile.Close

We used Split to create an array named    fields   that contains each field that was in the line that we read.  What is an array?  Think of it like a drawer in a file cabinet.  A single file drawer holds multiple files, right?  Well, an array is a single variable that holds multiple values.  They are accessed like this:

我们使用Split创建了一个名为fields的数组,其中包含我们所读行中的每个字段。 什么是数组? 可以将它想象成文件柜中的抽屉。 一个文件抽屉可以容纳多个文件,对吗? 数组是一个包含多个值的变量。 可以这样访问它们:

Set oFS = CreateObject("Scripting.FileSystemObject")
Set oFile = oFS.OpenTextFile("c:\MyFile.CSV",1)
data = oFile.Readline
fields = Split(data,",")
WScript.Echo(fields(0))
WScript.Echo(fields(1))
WScript.Echo(fields(2))
oFile.Close

Arrays are always numbered beginning with 0, and are referred to as being "zero-based".  So, the example code above would read the line, split the line of text with all the fields on the commas in the line, and store each field in a separate array position.  But what if there are more than 3 fields?  What if there are 100 fields?  We don't want to have to type out 100 lines of    WScript.Echo(fields(100)), so what can we do?  Well

数组始终从0开始编号,并称为“从零开始”。 因此,上面的示例代码将读取该行,将文本行与该行中逗号的所有字段分开,并将每个字段存储在单独的数组位置。 但是,如果有3个以上的字段怎么办? 如果有100个字段怎么办? 我们不需要键入100行的WScript.Echo(fields(100)), 所以,我们能做些什么? 好

Set oFS = CreateObject("Scripting.FileSystemObject")
Set oFile = oFS.OpenTextFile("c:\MyFile.CSV",1)
data = oFile.Readline
fields = Split(data,",")
For i = 0 to UBound(fields)
    WScript.Echo(fields(i))
Next
oFile.Close

is one way of doing it.  Note the use of "UBound(fields)"   This returns an integer value that tells you what the Upper Boundary of the array is.  Since you can have arrays of any size, it is very important that you know how large the array is so that you don't get an "Index out of Bounds" error generated.  Another way to handle this would be:

是做到这一点的一种方法。 请注意“ UBound(fields)”的使用,这将返回一个整数值,该值告诉您数组的上边界是什么。 由于可以有任意大小的数组,因此知道数组的大小非常重要,这样就不会产生“超出范围的索引”错误。 处理此问题的另一种方法是:

Set oFS = CreateObject("Scripting.FileSystemObject")
Set oFile = oFS.OpenTextFile("c:\MyFile.CSV",1)
data = oFile.Readline
fields = Split(data,",")
For Each field in fields
    WScript.Echo(field)
Next
oFile.Close

That will automatically go through the array one item at a time and echo the contents.  

它将自动一次一次遍历数组并回显内容。

Another useful string method is  InStr   For example, say you want to read an entire file, and every line that contains the word "the" should be echoed.

另一个有用的字符串方法是InStr。例如,假设您要读取整个文件,并且应回显包含单词“ the”的每一行。

Set oFS = CreateObject("Scripting.FileSystemObject")
Set oFile = oFS.OpenTextFile("c:\MyFile.txt",1)
Do While Not oFile.AtEndOfStream
    data = oFile.Readline
    If InStr(data,"the") Then WScript.Echo data
Loop
oFile.Close

In that code is also the control logic to read an entire file, using  AtEndOfStream.  

在该代码中,还有使用AtEndOfStream读取整个文件的控制逻辑。

Now, say you had that same file, but you wanted to replace the word "apple" with the word "orange" everywhere in the file.

现在,假设您拥有相同的文件,但是您想在文件中的所有位置将单词“ apple”替换为“ orange”。

Set oFS = CreateObject("Scripting.FileSystemObject")
Set inputFile = oFS.OpenTextFile("c:\MyFile.txt",1)
Set outputFile = oFS.CreateTextFile("c:\newfile.txt")
Do While Not inputFile.AtEndOfStream
    data = inputFile.Readline
    data = Replace(data,"apple","orange")
    outputFile.Writeline(data)
Loop
inputFile.Close
outputFile.Close

The  Replace method is used like this:  

替换方法的用法如下:

    Replace( stringToSearch, stringToBeReplaced, stringToReplaceItWith )  

Replace(

Pretty easy.

挺容易。

So, to copy files or folders:

因此,要复制文件或文件夹:

Set oFS = CreateObject("Scripting.FileSystemObject")
oFS.CopyFile(Source, Destination)
oFS.CopyFolder(Source, Destination)

Deleting files/folders is similar:

删除文件/文件夹类似:

Set oFS = CreateObject("Scripting.FileSystemObject")
oFS.DeleteFile(path)
oFS.DeleteFolder(path)

So, now that we've got some basic filesystem stuff down, adding logging to our scripts should be a piece of cake.  An example on logging errors was provided in the previous installment of this series, be sure to take a look at it if you haven't already.  The next installment will cover functions and subroutines, why they're useful, and how to write them.  Until then...

因此,既然我们已经掌握了一些基本的文件系统知识,那么向脚本添加日志记录应该是小菜一碟。 在本系列的前一部分中,提供了有关记录错误的示例,如果尚未阅读,请确保对其进行查看。 下一部分将介绍函数和子例程,它们为何有用以及如何编写。 直到那时...

Happy coding,

编码愉快,

exx

exx

翻译自: https://www.experts-exchange.com/articles/3330/VBScript-for-Windows-System-Administrators-Part-3.html

vbscript

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值