如果不存在,Powershell 将文本添加到文件
Powershell add text to files if does not exist
我想创建一个将文本添加到 *.jsp *.sh *.cmd 文件的 Powershell 脚本。我还希望它检查文本是否已存在于该文件中,如果存在则跳过该文件。到目前为止,我已经找到 Select-String ,它将在文件中找到文本。然后我如何使用此信息将文本添加到没有文本的文件顶部?我还发现 Add-Content 似乎添加了我想要的内容,但我想在一开始就这样做,并且有一些逻辑不只是每次我 运行 ps1 时都重新添加它.
Select-String -Pattern "TextThatIsInMyFile" -Path c:\Stuff\batch\*.txt
Add-Content -Path "c:\Stuff\batch\*.txt" -Value "`r`nThis is the last line"
参考手册:https://technet.microsoft.com/en-us/library/hh849903.aspx
具体来说:
产出
输出类型是 cmdlet 发出的对象的类型。
• Microsoft.PowerShell.Commands.MatchInfo 或 System.Boolean
默认情况下,输出是一组 MatchInfo 对象,一个对应找到的每个匹配项。
如果使用 Quiet 参数,输出是一个 布尔值 指示是否找到模式。
我还认为您还需要为每个文件执行此操作。所以(大概):
$files = Get-ChildItem "C:\Stuff\batch" -Filter *.txt
for ($i=0; $i -lt $files.Count; $i++)
{
$filename = $files[$i].FullName
$b = Select-String -Quiet -Pattern "TextThatIsInMyFile" -Path $fileName
if (-not $b)
{
Add-Content -Path $fileName -Value "`r`nTextThatIsInMyFile"
}
}
我对此进行了测试,我认为它可以满足您的需求,即将文本添加到没有文本的文件末尾,并且不会多次执行此操作。
与@MikeWise 的非常相似,但优化得更好一些。我让它提取数据并让提供者过滤返回的文件(比事后过滤好得多)。然后我使用 Select-String
的 -quiet
参数将它传递给 Where
语句,以向 Where 提供布尔值 $true/$false。这样只会查看您想要查看的文件,只有那些缺少您需要的文本的文件才会被更改。
Get-ChildItem "C:\Stuff\Batch\*" -Include *.jsp,*.sh,*.cmd -File |
Where{!(Select-String -SimpleMatch "TextThatIsInMyFile" -Path $_.fullname -Quiet)} |
ForEach{
$Path = $_.FullName
"TextThatIsInMyFile",(Get-Content $Path)|Set-Content $Path
}
编辑: 如您所见,\*
不适用于 -Recursive
。如果需要递归,请使用以下内容:
Get-ChildItem "C:\Stuff\Batch" -Include *.jsp,*.sh,*.cmd -File -Recurse
我想创建一个将文本添加到 *.jsp *.sh *.cmd 文件的 Powershell 脚本。我还希望它检查文本是否已存在于该文件中,如果存在则跳过该文件。到目前为止,我已经找到 Select-String ,它将在文件中找到文本。然后我如何使用此信息将文本添加到没有文本的文件顶部?我还发现 Add-Content 似乎添加了我想要的内容,但我想在一开始就这样做,并且有一些逻辑不只是每次我 运行 ps1 时都重新添加它.
Select-String -Pattern "TextThatIsInMyFile" -Path c:\Stuff\batch\*.txt
Add-Content -Path "c:\Stuff\batch\*.txt" -Value "`r`nThis is the last line"
参考手册:https://technet.microsoft.com/en-us/library/hh849903.aspx
具体来说:
产出
输出类型是 cmdlet 发出的对象的类型。 • Microsoft.PowerShell.Commands.MatchInfo 或 System.Boolean 默认情况下,输出是一组 MatchInfo 对象,一个对应找到的每个匹配项。 如果使用 Quiet 参数,输出是一个 布尔值 指示是否找到模式。
我还认为您还需要为每个文件执行此操作。所以(大概):
$files = Get-ChildItem "C:\Stuff\batch" -Filter *.txt
for ($i=0; $i -lt $files.Count; $i++)
{
$filename = $files[$i].FullName
$b = Select-String -Quiet -Pattern "TextThatIsInMyFile" -Path $fileName
if (-not $b)
{
Add-Content -Path $fileName -Value "`r`nTextThatIsInMyFile"
}
}
我对此进行了测试,我认为它可以满足您的需求,即将文本添加到没有文本的文件末尾,并且不会多次执行此操作。
与@MikeWise 的非常相似,但优化得更好一些。我让它提取数据并让提供者过滤返回的文件(比事后过滤好得多)。然后我使用 Select-String
的 -quiet
参数将它传递给 Where
语句,以向 Where 提供布尔值 $true/$false。这样只会查看您想要查看的文件,只有那些缺少您需要的文本的文件才会被更改。
Get-ChildItem "C:\Stuff\Batch\*" -Include *.jsp,*.sh,*.cmd -File |
Where{!(Select-String -SimpleMatch "TextThatIsInMyFile" -Path $_.fullname -Quiet)} |
ForEach{
$Path = $_.FullName
"TextThatIsInMyFile",(Get-Content $Path)|Set-Content $Path
}
编辑: 如您所见,\*
不适用于 -Recursive
。如果需要递归,请使用以下内容:
Get-ChildItem "C:\Stuff\Batch" -Include *.jsp,*.sh,*.cmd -File -Recurse