我有一个带有 CRLF 行结尾的文件,我需要将其转换为 LF。这个 sed 命令可以做到这一点:
sed -E -i "s/\r\n/\n/" file.txt
.
我已经使用 msys2 在我的 Windows 11 中安装了 sed。所以,如果我在 Powershell 中执行上面的 sed 命令,它会成功执行并将 CRLF 转换为 LF。
但是,如果我在 Powershell 中的 bash 中执行上面的 sed 命令,它会在控制台没有输出的情况下完成。但是它无法将 CRLF 转换为 LF。
相反,如果我运行 sed 命令来替换单词字符,它会在 Powershell 和 Powershell bash 中正确执行。所以我认为这与 bash 处理 CRLF 的方式有关。
现在,如何使用 sed 在 Powershell bash 中将 CRLF 转换为 LF?
在您的 WSL
bash
会话中使用以下命令,以便执行文件从 \r\n
(CRLF,Windows 格式)到 \n
(LF,Unix 格式)换行符(行尾)的就地转换:[1]
sed -i 's/\r$//' file.txt
或者,如果您不介意将文件作为一个整体阅读,使用GNU
sed
的-z
选项和g
正则表达式选项进行global匹配(查找all匹配):
sed -i -z 's/\r\n/\n/g' file.txt
您的问题与 PowerShell 无关;相反,您的 sed
命令逻辑存在问题:
sed
默认情况下读取输入行,并且removes每个尾随的换行符。
sed
脚本运行的 no行默认包含
\n
,因此尝试匹配 s
的替换(\r\n
命令)总是 no-op。因为
sed
只考虑\n
(LF)alone换行:
\r\n
结尾的行将结束\r
(CR)当对它们执行sed
操作时。s/\r$//
因此从每一行中删除尾随的\r
,并且-在将修改后的行写回文件时-以just\n
终止每一行,因此实际上只有\n
(LF)换行符仍然存在。
注:
为什么 sed -E -i "s/\r\n/\n/" file.txt
为你工作的唯一原因是 MSYS 附带的
sed
实现具有Windows 的特殊行为:
reading files, it recogns both \n
(LF)and
\r\n
(CRLF) as newlines.
写文件时,仅使用\n
(LF)
,下面的命令就足够了,即提供一个空脚本:
s/\r\n/\n/
实际上有no效果——在any
sed
实现。换句话说:只是 MSYS
sed
实现的default行为恰好为您执行了所需的转换。
[1] 要执行 相反 转换 - 从 LF-only 到 CRLF 换行符,请使用 sed -i 's/$/\r/' file.txt
,如jdweng 注释。