【问题标题】:Bash CRLF - new lines at the end of documentBash CRLF - 文档末尾的新行
【发布时间】:2016-03-04 18:11:19
【问题描述】:

我在 StackOverflow 和 Google 叔叔上查看了很多问题,但不知何故我仍然无法破解它。

我有一个由 SSRS 自动导出的 CSV 文件。不幸的是,导出插件很旧,它们在文件末尾放置了两个换行符和回车:

00000c0: 6b7c 3230 2d46 6562 2d31 360d 0a0d 0a k|20-Feb-16....

我尝试了很多 sed 替换,但它似乎只删除了一行。

例如简单化

sed -i '/^\s*$/d'

还尝试将\s 替换为[[:space:]](也可以,但仅在一行上)

十六进制转储的最后一行如下所示:

00000c0: 6b7c 3230 2d46 6562 2d31 360d 0a k|20-Feb-16..

我尝试过类似的方法:

sed -i 's/\x0D\X0A//g' <file> 但是这不会在最后替换两个 0d0a

任何帮助将不胜感激

【问题讨论】:

标签: bash shell sed newline


【解决方案1】:

以下命令应该适合您:

sed 's/\x0d//;/^$/d'

我正在删除所有回车符并删除空行。

试试看,像这样:

echo -e "foo\x0a\x0d\x0a" | sed 's/\x0d//;/^$/d' | xxd
00000000: 666f 6f0a                                foo.

【讨论】:

  • 这很有趣,我使用了它,现在 hexdump 的最后一行看起来像:00000f0: 2043 6f6f 6b7c 3033 2d4d 6172 2d31 360a Cook|03-Mar-16. 为什么第一个 x0a 会消失,而第二个不会?
  • 那是因为sed 将(通常)“看不到”换行符。它以每行为基础运行。最后一行以行分隔符结束也是很好和正确的。在类似 UNIX 的系统上,另一个回车符不会被识别为行分隔符。这就是为什么它可以被 sed 删除。
  • 但是如果文件的最终目的地是基于 Windows 的,那么在那里运行的进程会将 LF 视为新行,对吗?
  • 不,如果文件的最终目的地是 Windows,您需要将所有行尾转换为 \0xd\0xa。在这种情况下,sed '/^\x0d$/d' 应该可以工作。它只是删除了尾随的空行,但保持 Windows 回车完整。
  • 问题是我不希望文件末尾的那些行结尾,所以基本上必须从文件末尾删除 \0xd\0xa\0xd\0xa 部分。
【解决方案2】:

“忘记最后两行。”

# gnu!
head -n -2 foo.csv > foo.csv.new

“哦,ed(或 ex/vi/vim),杀掉最后两行。”

ed foo.csv << EOF
$
-1,$d
w foo.csv.new
q
EOF

# ex/vi/vim: change this to vi -c "the whole trunk".

“我喜欢 sed。我也喜欢 sed。” (我没有)

sed -i -e '$d' foo.csv; sed -i -e '$d' foo.csv

“我应该杀了这个吗?”

[[ $(tail -n 2 foo.csv) == $'\r\n\r\n' ]]

“Vim,你能自己测试一下吗?”

# I don't write vimscript.

“PERL?”

# I don't write Perl.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 2015-06-18
    • 2014-05-28
    相关资源
    最近更新 更多