【问题标题】:Find record length independent of EOL characters查找与 EOL 字符无关的记录长度
【发布时间】:2020-05-28 14:20:05
【问题描述】:

我正在使用 awk 来查找记录的长度。

awk '{print  length($0),$0}'

它适用于 Unix 行尾 <LF>,但将 DOS 行尾 <CR><LF> 视为字符

有没有办法解决这个问题。

【问题讨论】:

  • “它适用于 Unix 行尾 <LF>” - 正确。 “但将 DOS 行结尾 <CR><LF> 视为一个字符” - 不,它认为 <CR> 一个字符就像任何其他字符一样,仅此而已。没有办法知道foo<CR><LF> 的给定输入是否是foo,后跟以<CR><LF>foo<CR> 结尾的DOS 行,然后是仅以<LF> 结尾的UNIX 行。您需要真正考虑一下您的目标是什么,该脚本试图找出它正在读取的输入的意图。

标签: shell awk eol


【解决方案1】:

只需将awk 中的记录分隔符用于 DOS 行尾 (\r\n),这样它们就不会被视为行的一部分。在 Unix 世界中,通常以 \n 结尾,这恰好是默认的 RS 值。

awk -v RS="\r\n" '{ print  length($0), $0 }'

您还可以使用sub()/gsub() 函数在每一行替换这些字符并应用您的操作。

要同时处理 Unix/DOS 风格的结尾,请将 RS 定义设为正则表达式,以使 \r 出现零次或多次出现

awk -v RS="[\r]*\n" '{ print  length($0), $0 }'

GNU awk 仅支持这两种变体,因为 POSIX 版本不“接受”多字符记录分隔符。

【讨论】:

  • 谢谢@Inian。但是该代码不适用于带有 \n 的文件。我收到了这两种类型的文件,并希望找到长度,而与 EOL 无关
  • 谢谢。这有效 `awk -v RS="\r*\n" '{ print length($0), $0 }' `
  • @kvantour:我确实对两者都是认真的,但现在明确表示了。谢谢
  • ITYM RS='\r?\n' 所以你不要在 DOS 行结束 \r\n 之前删除 \rs 但这有点脆弱,因为没有办法告诉foo\r\n 的给定输入如果那是foo 后跟 DOS 行结尾或 foo\r 后跟 UNIX 行结尾。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
  • 2017-06-13
  • 2013-05-03
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
  • 1970-01-01
相关资源
最近更新 更多