【问题标题】:How can I remove characters from a line in a text file without renaming the file?如何在不重命名文件的情况下从文本文件的行中删除字符?
【发布时间】:2019-09-27 10:58:27
【问题描述】:

我希望能够获取文件夹中的文件并将其以批处理或 PowerShell 的形式写入文本文件。文本文件中的输出应该有 FileName、NewFileName、DateModified。 FileName 是文件在被程序摄取和输出之前的名称。 NewFileName 是从程序输出并存储在输出文件夹中的文件的名称。

下面的 PowerShell 脚本是我用来获取文件的名称和修改日期以显示在文本文件中的。

Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\ -Recurse |
    Select-Object @{n='File'; e={$_.Name + "," + $_.LastWriteTime}} |
    Out-File "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\Log.txt"
Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\ -Recurse |
    Select-Object @{n='File'; e={$_.Name + "," + $_.LastWriteTime}} |
    Out-File "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\Log.txt"

但是,我想要的输出是被摄取的原始文件名。

在程序中摄取之前的文件名:Some_Name_file.mxf

摄取后的新文件名:random_exactly_37_characters_FileName.mxf_random_exactly_11_characters

原来的文件已经不存在了,所以我可以只添加那个路径并说写它的名字。那么有没有一种方法可以删除文件名前的 37 个字符和文件名末尾的最后 11 个字符,并将其写在同一个文本文件中。我不想重命名 NewFileName,因为它会更改日期修改参数。

【问题讨论】:

  • 为什么不使用 CSV 文件而不是纯文本。你可以使用Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\ -Recurse | Select-Object Name , LastWriteTime | Export-Csv -Path "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\Log.csv" -NoTypeInformation
  • 我可以使用 csv,但是如何删除名称前的 37 个字符和名称后的 11 个字符。还有-NoTypeInformation 做什么@Olaf
  • 请阅读 cmdlet Export-Csv 的帮助以了解它及其参数。您甚至可以尝试使用参数运行命令,一次不运行,然后自己比较结果。如果总是要删除 37 个字符,则可以使用 Powershell 中字符串可用的 substring 方法。例如'ArbitraryString_With some Cahrachters Keep This and forget the rest'.Substring(38, 9)

标签: string powershell random cmd


【解决方案1】:

这假定您要删除的内容中包含下划线和文件扩展名,并且您始终希望删除 37 个前导字符和 11 个后续字符。您可以使用文件名的Substring 属性来执行此操作。

$audioFiles = Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\ -File -Recurse |
    Select-Object @{n='File';e={$_.Name.Substring(37,($_.Name.Length-37-11))}},LastWriteTime
$audioFiles | Export-Csv "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\Log.csv" -NoTypeInformation

$videoFiles = Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\ -File -Recurse |
    Select-Object @{n='File';e={$_.Name.Substring(37,($_.Name.Length-37-11))}},LastWriteTime 
$videoFiles | Export-Csv "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\Log.csv" -NoTypeInformation

请记住,子字符串字符索引从 0 开始,到 Length-1 结束。


另一种方法是使用-replace 运算符,它使用正则表达式进行字符串匹配。

$audioFiles = Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\ -File -Recurse |
    Select-Object @{n='File';e={$_.Name -replace '^.{37}(.*).{11}$','$1'}},LastWriteTime
$audioFiles | Export-Csv "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\Log.csv" -NoTypeInformation

$videoFiles = Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\ -File -Recurse |
    Select-Object @{n='File';e={$_.Name -replace '^.{37}(.*).{11}$','$1'}},LastWriteTime
$videoFiles | Export-Csv "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\Log.csv" -NoTypeInformation
  • . 匹配任何非换行符。
  • {N} 匹配之前的机制(本例中为.)N 次。
  • (.*) 是一个捕获组 ($1),它匹配任何字符,直到正好剩下 11 个字符。
  • ^ 表示字符串的开头。
  • $ 表示字符串结束。

基本上,整个文件名被替换为中间的子字符串。

【讨论】:

  • 这两个我都试过了,这个代码的问题是它创建了一个新的文件名,而不是把它全部放在一个文本文件中
  • 文本文件中你想要的数据格式是什么?在您的示例中,您将一个对象输出到文本文件,这很难看。您想要一个包含文件列和文件名的 CSV 输出吗?
  • 输出应该是字符串的 37 开始和 11 结束后的名称被删除,原始文件名,修改日期所有列表向下附加列表。不管是CSV还是普通的txt文件
猜你喜欢
  • 1970-01-01
  • 2013-10-08
  • 2021-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多