使用Powershell批量修改目录

问题描述 投票:2回答:3

我需要更新许多txt文件中的目录

Input files:
1.txt
using c:\data\1.dta
its own data

2.txt
using c:\data\2.dta
its own data

3.txt
using c:\data\3.dta
its own data

Expected Output files:
1.txt
using C:\Data\Subfile\1.dta
its own data

2.txt
using C:\Data\Subfile\2.dta
its own data

3.txt
using C:\Data\Subfile\3.dta
its own data

我已经尝试了 - 但是结果很奇怪:要么所有文件都有相同的结果,要么拥有所有新目录(卖得低于)

我想将旧路径更新到所有文件中的newpath。代码如下:

$pathway='C:Data\Subfile\*.txt'
$oldpath='c:\\data\\'
$newpath='C:\Data\Subfile\'
$content=Get-Content -path $pathway

方法1:

$newline=((Get-Content -path $pathway -TotalCount 1) -replace $oldpath,$newpath)
$content[0]= $newline

This method will include all updated directories in every file:
Wrong output:
1.txt
using C:\Data\Subfile\1.txt
using C:\Data\Subfile\2.txt
using C:\Data\Subfile\3.txt
its own data

2.txt
using C:\Data\Subfile\1.txt
using C:\Data\Subfile\2.txt
using C:\Data\Subfile\3.txt
its own data

方法2:

$content[0]=$content[0]-replace $oldpath,$newpath

This method will cause all file has the same new directory:
Wrong output:
1.txt
using C:\Data\Subfile\1.txt 
its own data

2.txt
using C:\Data\Subfile\1.txt 
its own data

3.txt
using C:\Data\Subfile\1.txt 
its own data

$content | Set-Content -Path $pathway

有人可以帮助我吗?我希望每个文件都有相应的新目录。对于1.txt我想要C:\ Data \ Subfile \ 1.txt,对于2.txt我想要C:\ Data \ Subfile \ 2.txt等。

非常感谢!

powershell
3个回答
2
投票

我对你想要的最终内容有点不清楚。是using C:\Data\Subfile\1.txt还是using C:\Data\Subfile\1.dta?我想你要求以下但如果不让我知道。根据文件的大小,您可能会遇到速度/性能问题。

如果这些是您的输入文件及其内容:

C:\data\Subfile\1.txt
  using c:\data\1.dta
  its own data...

C:\data\Subfile\2.txt
  using c:\data\2.dta
  its own data...

C:\data\Subfile\3.txt
  using c:\data\3.dta
  its own data...

这个:

Get-ChildItem c:\data\Subfile\*.txt | Foreach-Object{
    #Read in all content lines and replace c:\data\ with c:\data\subfile
    $content = Get-Content $_.FullName | %{$_ -replace 'c:\\Data\\', 'c:\Data\Subfile\' }
    #write the new data to file
    $content | Set-Content $_.FullName
}

这导致以下结果:

C:\data\Subfile\1.txt
  using c:\Data\Subfile\1.dta
  its own data...

C:\data\Subfile\2.txt
  using c:\Data\Subfile\2.dta
  its own data...

C:\data\Subfile\3.txt
  using c:\Data\Subfile\3.dta
  its own data...

2
投票

使用lookarounds,您可以精确定义插入文本的位置,而无需重复搜索模式。

foreach ($File in Get-ChildItem 'C:\Data\Subfile\*.txt'){
    (Get-Content $File -raw) -replace "(?<=C:\\data\\)(?=\d\.dta)","Subfile\" |
     Set-Content $File
}
  • "(?<=C:\\data\\)是一个积极的后视零长度断言,
  • (?=\d\.dta)是一个积极的前瞻性零长度断言,
  • 替换文本插入这两者之间。
  • 这比其他方法更安全,因为它可重复,而不再插入Subfile\

1
投票

这是一种完成工作的方法。 [笑]它的作用......

  • #region/#endregion标记之间只是为了使文件可以使用
  • 读取文件列表
  • 通过该列表迭代
  • 加载每个内容
  • 用新的dir替换旧的dir
  • 最后写出了新的内容

这是代码......

#region - Make files to work with
$Null = New-Item -Path "$env:TEMP\TestFiles" -ItemType Directory -ErrorAction SilentlyContinue

$1stFileName = "$env:TEMP\TestFiles\1.txt"
$1stFileContent = @'
using c:\data\1.dta
its own data
'@ -split [System.Environment]::NewLine |
    Set-Content -LiteralPath $1stFileName

$2ndFileName = "$env:TEMP\TestFiles\2.txt"
$2ndFileContent = @'
using c:\data\2.dta
its own data
'@ -split [System.Environment]::NewLine |
    Set-Content -LiteralPath $2ndFileName

$3rdFileName = "$env:TEMP\TestFiles\3.txt"
@'
using c:\data\3.dta
its own data
'@ -split [System.Environment]::NewLine |
    Set-Content -LiteralPath $3rdFileName
#endregion - Make files to work with

$OldDir = 'c:\data'
$NewDir = 'c:\data\SubDir'

$SourceDir = "$env:TEMP\TestFiles"

$FileList = Get-ChildItem -LiteralPath $SourceDir -Filter '*.txt' -File

foreach ($FL_Item in $FileList)
    {
    $NewContent = Get-Content -LiteralPath $FL_Item.FullName |
        ForEach-Object {
            $_.Replace($OldDir, $NewDir)
            }
    $NewContent |
        Set-Content -LiteralPath $FL_Item.FullName
    }

脚本运行前后的文件1.txt的内容...

# before ...
using c:\data\1.dta
its own data    

# after ...
using c:\data\SubDir\1.dta
its own data
© www.soinside.com 2019 - 2024. All rights reserved.