我有一个包含以下信息的txt文件:
第1页
学生1数据
FF换页符(可能出现,也可能不出现)[INCLUDE in parsed file]
第2页
学生1数据
学生1数据
*成绩单结束
FF换页符(明确出现在此位置)[不包含在解析文件中]
第1页
学生2数据
学生2数据
FF换页符(可能出现,也可能不出现)[INCLUDE in parsed file]
第2页
学生2数据
*成绩单结束〈
FF换页符(明确出现在此位置)[不包含在解析文件中]
第1页
学生3数据
学生3数据
学生3数据
FF换页符(可能出现,也可能不出现)[INCLUDE in parsed file]
*成绩单结束
FF换页符(明确出现在此位置)[不包含在解析文件中]
我正在尝试解析出数据,这样我就可以得到三个单独的文件,并删除只出现在"记录结束"行之后的表单提要。
我最终得到三个文件:
包含"学生1数据"的日期_EDI_TRANSCRIPT_1.txt
包含"学生2数据"的日期_EDI_TRANSCRIPT_2.txt
包含"学生3数据"的日期_EDI_TRANSCRIPT_3.txt
但是,解压缩文件中的换页在每个文件的开头。我想从文件的开头和结尾删除它。
我得到这个:
我想得到这个:
我的代码是:
$data = Get-Content "C:\EDICleanUp\1_ToBeProcessed\edi.txt" #Reading file
$Transcript = "_EDI_TRANSCRIPT_"
$Tdate = get-date -Format yyyy-MM-dd
$ProcessedFilePath = "C:\EDICleanUp\2_Processed"
$Complete = "C:\EDICleanUp\3_Original"
$ToBeProcessed = "C:\EDICleanUp\1_ToBeProcessed\edi.txt"
$fileIndex = 1; #To create file name
for ($itr = 0; $itr -le $data. Length; $itr++){
if($data[$itr] -eq "********** END OF TRANSCRIPT **********"){
$fileIndex+=1;
continue;
}
if((Test-Path "$ProcessedFilePath$Tdate$Transcript$fileIndex.txt") -eq $false){
New-Item "$ProcessedFilePath$Tdate$Transcript$fileIndex.txt" -ItemType "File"
}
#Append text to the file
Add-Content "$ProcessedFilePath$Tdate$Transcript$fileIndex.txt" $data[$itr]
}
##Move original file to completed directory
Move-item $ToBeProcessed $Complete
我"认为"问题在于:
if($data[$itr] -eq "********** END OF TRANSCRIPT **********"){
$fileIndex+=1;
我找不到合适的代码来查找硬返回/表单提要。
我尝试了以下变体:
'*******\s\s [脚本结束]********+\f'
但运气不好。
任何投入都将不胜感激。
1条答案
按热度按时间hmae6n7t1#
我建议使用
Get-Content
-Raw
一次读取整个文件,并使用基于regex的-split
operator将文件拆分为感兴趣的块,而不是逐行处理。一个简单的例子:
[regex]::Escape('********** END OF TRANSCRIPT **********') + '\r?\n\f'
是用于拆分文件内容的正则表达式:[regex]::Escape('********** END OF TRANSCRIPT **********')
转义搜索字符串的文字部分,以便在正则表达式中使用(实际上,此\
-转义*
字符,它们是正则表达式元字符。\r?\n
匹配Windows格式的CRLF换行符(\r\n
)或Unix的LF换行符(\n
)\f
与FF字符匹配。END OF TRANSCRIPT
示例都由相同的固定数量的*
字符和空格包围。"..."
)(参见下一节),并通过-split
的SimpleMatch
选项进行*常量 * 拆分;例如:-ne ''
从结果中过滤掉空行块(如果文件以分隔符结尾,-split
会将其后的空字符串视为另一个元素)。Set-Content
一起使用,以动态确定每个结果行块的输出文件名。$nr
(输出文件序列号)是如何定义为hashtable(@{ ... }
)的,而不是直接定义为整数;这是必需的,因为delay-bind脚本块在调用者的 * child * 作用域中运行;参见this answer以获得解释。-f
运算符用于合成输出文件名。至于你所尝试的:
我尝试了以下变体:
'**********\s\s[END OF TRANSCRIPT]***********+\f'
只有. NET * regex引擎 *(由PowerShell的regex运算符在后台使用)才能理解
\s
和\f
等结构因此,要使用类似上面的操作,必须使用基于正则表达式的
-match
操作符,而不是-eq
操作符。然而,PowerShell * 确实 * 有用于某些ASCII范围控制字符的转义序列(但 * 没有 * 用于 * 抽象 *,如
\s
,以表示各种空白字符),这需要使用可扩展(双引号)字符串("..."
)和 * 反记号 *(```)转义序列,如"
f"`用于FF;在现代PowerShell (Core) 7+ edition中,还可以使用转义序列表示任何Unicode字符-请参见about_Special_Characters概念帮助主题