简体   繁体   English

如何在powershell中递归附加到文件名?

[英]How to recursively append to file name in powershell?

I have multiple .txt files in folders/their sub-folders.我在文件夹/它们的子文件夹中有多个 .txt 文件。

I want to append _old to their file names.我想将 _old 附加到他们的文件名。

I tried:我试过:

Get-ChildItem -Recurse | Rename-Item -NewName {$_.name -replace '.txt','_old.txt' }

This results in:这导致:

  1. Some files get updated correctly某些文件得到正确更新
  2. Some files get updated incorrectly - they get _old twice - example: .._old_old.txt某些文件更新不正确 - 它们得到 _old 两次 - 例如: .._old_old.txt
  3. There are few errors: Rename-Item : Source and destination path must be different.错误很少: Rename-Item : Source and destination path must be different.

To prevent already renamed files from accidentally reentering the file enumeration and therefore getting renamed multiple times, enclose your Get-ChildItem call in () , the grouping operator , which ensures that all output is collected first [1] , before sending the results through the pipeline:为了防止已重命名的文件意外地重新进入该文件列举,因此越来越改名多次附上您Get-ChildItem呼叫()分组操作,以保证所有输出首先收集[1],通过发送结果之前管道:

(Get-ChildItem -Recurse) |
  Rename-Item -NewName { $_.name -replace '\.txt$', '_old.txt' }

Note that I've used \\.txt$ as the regex [2] , so as to ensure that only a literal .请注意,我使用\\.txt$作为正则表达式[2] ,以确保只有文字. ( \\. ) followed by string txt at the end ( $ ) of the file name is matched, so as to prevent false positives (eg, a file named Atxt.csv or even a directory named AtxtB would accidentally match your original regex). ( \\. ) 后跟字符串txt在文件名的末尾( $ ) 匹配,以防止误报(例如,名为Atxt.csv的文件甚至名为AtxtB目录会意外匹配您的原始正则表达式)。

Note: The need to collect all Get-ChildItem output first arises from how the PowerShell pipeline fundamentally works: objects are (by default) sent to the pipeline one by one , and processed by a receiving command as they're being received .注意:收集所有Get-ChildItem输出的需要首先源于 PowerShell 管道的基本工作方式:对象(默认情况下)一个接一个地发送到管道,并在接收到它们时由接收命令处理。 This means that, without (...) around Get-ChildItem , Rename-Item starts renaming files before Get-ChildItem has finished enumerating files, which causes problems.这意味着,在Get-ChildItem周围没有(...)Rename-ItemGet-ChildItem完成枚举文件之前开始重命名文件,这会导致问题。 See this answer for more information about how the PowerShell pipeline works.有关 PowerShell 管道如何工作的更多信息,请参阅此答案
Tip of the hat to Matthew for suggesting inclusion of this information.Matthew 表示感谢,他建议包含此信息。

However, I suggest optimizing your command as follows:但是,我建议按如下方式优化您的命令:

(Get-ChildItem -Recurse -File -Filter *.txt) | 
  Rename-Item -NewName { $_.BaseName + '_old' + $_.Extension }
  • -File limits the the output to files (doesn't also return directories ). -File将输出限制为文件(也不返回目录)。

  • -Filter is the fastest way to limit results to a given wildcard pattern. -Filter是将结果限制为给定通配符模式的最快方法。

  • $_.BaseName + '_old' + $_.Extension uses simple string concatenation via the sub-components of a file name. $_.BaseName + '_old' + $_.Extension通过文件名的子组件使用简单的字符串连接。

    • An alternative is to stick with -replace :另一种方法是坚持使用-replace
      $_.Name -replace '\\.[^.]+$', '_old$&'

Note that if you wanted to run this repeatedly and needed to exclude files renamed in a previous run, add -Exclude *_old.txt to the Get-ChildItem call.请注意,如果您想重复运行此操作并需要排除在前一次运行中重命名的文件,请将-Exclude *_old.txt添加到Get-ChildItem调用中。


[1] Due to a change in how Get-ChildItem is implemented in PowerShell [Core] 6+ (it now internally sorts the results, which invariably requires collecting them all first), the (...) enclosure is no longer strictly necessary , but this could be considered an implementation detail, so for conceptual clarity it's better to continue to use (...) . [1] 由于在PowerShell [Core] 6+ 中实现Get-ChildItem的方式发生了变化(它现在在内部对结果进行排序,这总是需要首先收集它们), (...)外壳不再是绝对必要的,但这可以被视为一个实现细节,因此为了概念清晰,最好继续使用(...)

[2] PowerShell's -replace operator operates on regexes (regular expressions); [2] PowerShell 的-replace运算符对正则表达式(正则表达式)进行操作; it doesn't perform literal substring searches the way that the [string] type's .Replace() method does.它不会像[string]类型的.Replace()方法那样执行文字子字符串搜索。

The below command will return ALL files from the current folder and sub-folders within the current directory the command is executed from.下面的命令将返回当前文件夹和执行命令的当前目录中的子文件夹中的所有文件。

Get-ChildItem -Recurse

Because of this you are also re-turning all the files you have already updated to have the _old suffix.因此,您还需要将已更新的所有文件重新设置为具有 _old 后缀。

What you need to do is use the -Include -Exclude paramters of the Get-Childitem Cmdlet in order to ignore files that already have the _old suffix, and meet your include criteria, for example.例如,您需要做的是使用 Get-Childitem Cmdlet 的 -Include -Exclude 参数来忽略已经具有 _old 后缀的文件,并满足您的包含条件。

Get-ChildItem -Recure -Include "*.txt" -Exclude "*_old"

Then pipe the results into your re-name item command然后将结果通过管道传输到您的重命名项目命令中

Get-ChildItem cmdlet explanation can be found here.可以在此处找到 Get-ChildItem cmdlet 说明。

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Powershell 批量添加/追加文本到文件名 - Powershell Batch Add/Append text to a file name 将变量名称和日期附加到PowerShell文件输出 - Append variable name and date to PowerShell file output 使用 powershell 在文件名中附加字符串 - Append string in file name using powershell 使用Powershell,如何在文件名的特定部分中以“-”替换“ 0”的方式递归更改文件名? - Using Powershell, how can I change filename recursively in a way to replace '0' with '-' in specific part of file name? 如何在Powershell中附加到日志文件? - How to append to a log file in powershell? 如何根据文件名从多个 .txt 文件中提取字符串并将它们附加到 Powershell 上的新文件中? - How to pull strings from multiple .txt files based on file name and append them to a new file on Powershell? 在PowerShell中,如何递归复制目录并同时更改其名称 - In PowerShell, how to copy a directory recursively and change its name at the same time 如何使用 PowerShell 递归删除具有特定名称的文件夹? - How can I recursively delete folder with a specific name with PowerShell? 如何在powershell中的多个文件夹中递归更改名称 - how to recursively change name across several folders in powershell 如何使用Powershell在文件中动态附加时间 - How to dynamically append time in a file using Powershell
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM