在文件的所有行中将^M替换为<space>

3

我有一个日志文件,其中包含^M字符。我想用一个空格替换^M字符。
我尝试了以下变化:

(Get-Content C:\temp\send.log) | Foreach-Object {$_ -replace "^M", ' '} | Set-Content C:\temp\send.out  

输出文件包含每个 ^M 的换行符,这不是我要找的...
我试图解决的问题涉及检查文件的最后 $cnt 行:
$new = Get-Content $fn | Select-Object -Last $cnt;
$new

当我显示 $new 时,^M被解释为 CR/LF。如何移除/替换 ^M?感谢任何指导...

抱歉要成为“那个”人,但我需要定期在VIM中执行类似的操作 - 你必须使用PowerShell吗? - C.B.
是的,这是用于处理日志文件的较大PS模块的一部分。它将被多个用户使用,并且不能保证vim可用。 - Number8
你想替换一堆嵌入的回车符还是一堆字面上的 ^M?该文件使用 CRLF 行尾,对吧,就像一个普通的 Windows 文本文件?我正在努力澄清这个问题 - 我可以提供一个本地的 Windows 解决方案,但不是特别针对 PowerShell。 - foxidrive
3个回答

0

这是否只需要转义^字符就能解决?如果您只需要文件的最后$count行,则可以在Get-Content中使用“-Tail”参数。根据您是否需要区分大小写地匹配^M,您可能会选择使用“-creplace”而不是“-replace”。

Get-Content $inputfile -Tail $count | ForEach-Object { $_ -creplace '\^m',' ' } | Set-Content $outputfile

0

这不是一个答案,但既然你要求一些指针,这可能有助于澄清事情。

试试这个:

$new = Get-Content $fn | Select-Object -Last $cnt;
$new
$new.gettype()
$new[0].gettype()

我猜你会发现$new是一个对象数组,而$new[0]是一个字符串。我建议$new[0]不包含CR或LF或CRLF或任何类似的字符。当你要求完整显示$new时,我建议你得到的是每个字符串($new[0]后跟$new[1] ...),并插入CRLF作为分隔符。

如果我没错的话,用空格替换CR或CRLF对你没有任何好处。正是在输出到文件时插入CRLFs阻止了你的成功。

这是我解决你的问题所做的努力。


0

听起来好像^M没有被你的-replace方法替换,很可能replace方法试图替换字符串开头的大写字母M(^)。打开文件后,^M被解释为回车符。

也许在显示内容之前尝试替换回车符(^M):

(Get-Content C:\temp\send.log) | 
    Foreach-Object {$_ -replace "`r", ' '} | 
    Set-Content C:\temp\send.out

或者

$new = Get-Content $fn | Select-Object -Last $cnt;
$new.replace("`r"," ")

谢谢您的回复,nimizen,但是没有成功。我怀疑^M被转换为rn在流被读取时,所以在$new上进行处理(就像您的例子中)已经太晚了。 - Number8
另外需要指出的是,也许你需要用空格替换 "rn"。反引号 r 和反引号 n 会变成回车和换行符。 - Walter Mitty
第二点。当您使用get-content获取一个包含多行文本的文本文件时,您不会得到单个字符串,而是会得到一个字符串数组。根据您在问题中所做的管道操作,您似乎已经知道了这一点。但是,在这种情况下,我认为set-content不是将多行添加到输出的正确方法。 - Walter Mitty
哦,还有第三点,请查看变量$OFS。这是您控制PS将多个文本连接成文本文件的方式。 - Walter Mitty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接