【问题标题】:Replace text at specific line number with file name用文件名替换特定行号的文本
【发布时间】:2020-09-08 16:06:20
【问题描述】:

我有 400 多个 .vcf 文件,我想用文件名替换“FN:”行(第 4 行)。我查看了多种解决方案,但我似乎无法找到可以实现我正在寻找的东西,即使我知道有办法做到这一点。

这是我目前拥有的

文件名:姓氏第一名

BEGIN:VCARD
VERSION:3.0
N:lastName;firstName;;;
FN:firstName lastName
ADR:;;111 Main Rd;Columbia;MO;65202;
TEL;TYPE=mobile:(111) 222-3333
EMAIL;TYPE=work:email@gmail.com
BDAY:20000101
END:VCARD

这就是我想要实现的目标

保留“FN:”并将其后的文本替换为文件名文本。

BEGIN:VCARD
VERSION:3.0
N:lastName;firstName;;;
FN:LastNamefirstName
ADR:;;111 Main Rd;Columbia;MO;65202;
TEL;TYPE=mobile:(111) 222-3333
EMAIL;TYPE=work:email@gmail.com
BDAY:20000101
END:VCARD

这个 Powershell 脚本确实做了我想要的一半,但我真的很想把文件名输入到 replacementLineText 中。

# Set by user to their needs.
$filesToCheck = "C:\path\*.vcf"
$lineToChange = 4
$replacementLineText = "New Text"

# Gather list of files based on the path (and mask) provided by user.
$files = gci $filesToCheck

# Iterate over each file.
foreach ($file in $files) {

    # Load the contents of the current file.
    $contents = Get-Content $file

    # Iterate over each line in the current file.
    for ($i = 0; $i -le ($contents.Length - 1); $i++) {

        # Are we on the line that the user wants to replace?
        if ($i -eq ($lineToChange - 1)) {

            # Replace the line with the Replacement Line Text.
            $contents[$i] = $replacementLineText

            # Save changed content back to file.
            Set-Content $file $contents
        }
    }
}

任何意见或指导将不胜感激!

【问题讨论】:

    标签: powershell notepad++


    【解决方案1】:

    我真的很想把文件名输入到replacementLineText中。

    要接受所有目标文件的路径,您只需声明一个参数

    param(
      [Parameter(Mandatory = $true)]
      [string[]]$Path
    )
    
    $lineToChange = 4
    
    # Gather list of files based on the path (and mask) provided by user.
    $files = gci -Path $Path
    
    # ... rest of original script
    

    我对变量名做了一点修改——Path 是用于描述可扩展路径的字符串的惯用参数名,参数名一般应为大写。

    [Parameter()] 属性中与 $Path 关联的 Mandatory 标志意味着调用者必须提供一个值 - 否则 PowerShell 将提示它:

    PS C:\> .\script.ps1
    
    cmdlet script.ps1 at command pipeline position 1
    Supply values for the following parameters:
    Path:
    
    PS C:\> .\script.ps1 -Path "C:\path\*.vcf" # now it won't prompt
    

    有关参数的更多信息,请参阅 about_Functionsabout_Functions_Advanced_Parameters 帮助主题 - 虽然文档是关于 函数,但参数的规则及其声明对于脚本文件是相同的(您可以将脚本文件视为恰好位于文件系统而不是内存中的函数)


    gci(或Get-ChildItem)cmdlet 返回[FileInfo] 对象以及所有文件元数据,因此要将文件名用作循环内的替换值,您只需执行$file.Name

    $contents[$i] = "FN:$($file.Name)"
    # or using the -f format operator:
    $contents[$i] = "FN:{0}" -f $file.Name
    

    由于您已经知道要修改哪个索引(行号减 1),因此您可以跳过内部循环并改为:

    param(
      [Parameter(Mandatory = $true)]
      [string[]]$Path
    )
    
    $lineToChange = 4
    
    # Gather list of files based on the path (and mask) provided by user.
    $files = Get-ChildItem -Path $Path
    
    # Iterate over each file.
    foreach ($file in $files) {
    
        # Load the contents of the current file.
        $contents = Get-Content $file
    
        if($contents.Count -ge $lineToChange){
            # Replace the line with the Replacement Line Text.
            $contents[$lineToChange - 1] = "FN:$($file.Name)"
    
            # Save changed content back to file.
            Set-Content $file $contents
        }
    }
    

    【讨论】:

    • 感谢您的评论!但是,我不确定如何提取文件名(减去扩展名)并替换第四行的当前文本。我需要提取文件名并将第四行替换为 FN:[filename] 之类的内容,然后保存文件并继续下一个,依此类推。
    • @KyleW 所以你实际上不需要替换文本,你只需要当前文件名?
    • 是的!对于 **[string]$Replacement = "New Text" ** 而不是 "New Text",我想用一个真正是 PS 正在打开的文件名的变量替换它。
    • @KyleW Gotcha,一开始我没听懂。答案已更新
    猜你喜欢
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    相关资源
    最近更新 更多