在 WSL 中替换行尾时 sed 表现异常
sed behaving strangely when replacing line ends in WSL
我正在尝试使用 sed 在每一行末尾为目录中的所有 .txt 文件添加一些文本。这是我使用的确切命令:find . -name "*.txt" -exec sed -i 's/$/:orig/' {} +
预计:
https://pbs.twimg.com/media/EUr539_UMAAFqZM.jpg:orig
https://pbs.twimg.com/media/ENTrymcUwAAnd6_.jpg:orig
https://pbs.twimg.com/media/EIzzcrFUYAAgfUo.jpg:orig
这也是我在笔记本电脑 Linux Mint 19.2 中 运行 时实际得到的结果。但是当我在我的 Windows PC 上尝试它时,运行ning sed through Ubuntu 在 WSL 中,我得到的是:
https://pbs.twimg.com/media/EUr539_UMAAFqZM.jpg
:orig
https://pbs.twimg.com/media/ENTrymcUwAAnd6_.jpg
:orig
https://pbs.twimg.com/media/EIzzcrFUYAAgfUo.jpg:orig
如果我 cat
有问题的文件仍然在 Ubuntu 终端中,则显示的内容更像这样(有一些奇怪的空白使其看起来像 SO 中的列,但通常它们看起来都很混乱):
:orig://pbs.twimg.com/media/EUr539_UMAAFqZM.jpg :orig://pbs.twimg.com/media/ENTrymcUwAAnd6_.jpg https://pbs.twimg.com/media/EIzzcrFUYAAgfUo.jpg:orig
我知道 Windows 和 Linux 文本的格式不同,尤其是那一行结尾有问题,但我不确定这在这里是否重要。
任何人都可以阐明这种行为吗?我怎样才能使命令的行为一致?
问题是您的文件以 CRLF 结尾,但 WSL sed
仅使用 LF 和行结束。如果您 知道 它是 CRLF 风格,您可以通过三个步骤解决这个问题文件:
- 去掉 CR;
- 做你的改变;
- 把 CR 放回去。
那会是这样的:sed -i -e 's/\r$//' -e 's/$/:orig/' -e 's/$/\r/'
。
但是,这不适用于 UNIX 风格的文件,因为第一次替换什么都不做,但第三次替换会在每行的末尾放置一个 CR 字符,即使它最初不存在。如果您想要对两种 类型的文件都有效的东西,应该这样做:
sed -E 's/(\r)?$/:orig/'
这个捕获了行尾可选的CR,并放回替换中(如果不在原行,则不会放回) .
我正在尝试使用 sed 在每一行末尾为目录中的所有 .txt 文件添加一些文本。这是我使用的确切命令:find . -name "*.txt" -exec sed -i 's/$/:orig/' {} +
预计:
https://pbs.twimg.com/media/EUr539_UMAAFqZM.jpg:orig
https://pbs.twimg.com/media/ENTrymcUwAAnd6_.jpg:orig
https://pbs.twimg.com/media/EIzzcrFUYAAgfUo.jpg:orig
这也是我在笔记本电脑 Linux Mint 19.2 中 运行 时实际得到的结果。但是当我在我的 Windows PC 上尝试它时,运行ning sed through Ubuntu 在 WSL 中,我得到的是:
https://pbs.twimg.com/media/EUr539_UMAAFqZM.jpg
:orig
https://pbs.twimg.com/media/ENTrymcUwAAnd6_.jpg
:orig
https://pbs.twimg.com/media/EIzzcrFUYAAgfUo.jpg:orig
如果我 cat
有问题的文件仍然在 Ubuntu 终端中,则显示的内容更像这样(有一些奇怪的空白使其看起来像 SO 中的列,但通常它们看起来都很混乱):
:orig://pbs.twimg.com/media/EUr539_UMAAFqZM.jpg :orig://pbs.twimg.com/media/ENTrymcUwAAnd6_.jpg https://pbs.twimg.com/media/EIzzcrFUYAAgfUo.jpg:orig
我知道 Windows 和 Linux 文本的格式不同,尤其是那一行结尾有问题,但我不确定这在这里是否重要。
任何人都可以阐明这种行为吗?我怎样才能使命令的行为一致?
问题是您的文件以 CRLF 结尾,但 WSL sed
仅使用 LF 和行结束。如果您 知道 它是 CRLF 风格,您可以通过三个步骤解决这个问题文件:
- 去掉 CR;
- 做你的改变;
- 把 CR 放回去。
那会是这样的:sed -i -e 's/\r$//' -e 's/$/:orig/' -e 's/$/\r/'
。
但是,这不适用于 UNIX 风格的文件,因为第一次替换什么都不做,但第三次替换会在每行的末尾放置一个 CR 字符,即使它最初不存在。如果您想要对两种 类型的文件都有效的东西,应该这样做:
sed -E 's/(\r)?$/:orig/'
这个捕获了行尾可选的CR,并放回替换中(如果不在原行,则不会放回) .