【发布时间】:2022-01-07 01:17:10
【问题描述】:
我正在寻找从可能是二进制数据中计算尾随换行数的方法:
- 从标准输入读取
- 或已经在一个shell变量中(当然“二进制”至少不包括0x0) 使用 POSIX 或 coreutils 实用程序或 Perl。
这应该没有临时文件或FIFO。
当输入在 shell 变量中时,我已经有了以下(可能很丑但)可行的解决方案:
original_string=$'abc\n\n\def\n\n\n'
string_without_trailing_newlines="$( printf '%s' "${original_string}" )"
printf '%s' $(( ${#original_string}-${#string_without_trailing_newlines} ))
在上面的例子中给出3。
上面的想法是简单地减去字符串长度并使用命令替换的“特性”,它会丢弃任何尾随的换行符。
测试用例:
printf '' | function results in: 0
printf '\n' | function results in: 1
printf '\n\n' | function results in: 2
printf '\n\n\n' | function results in: 3
printf 'a' | function results in: 0
printf 'a\n' | function results in: 1
printf 'a\n\n' | function results in: 2
printf '\na\n\n' | function results in: 2
printf 'a\n\nb\n' | function results in: 1
对于NUL 是字符串一部分的特殊情况(无论如何,它只在从标准输入读取时起作用,而不是在通过变量在外壳中给出字符串时),结果是 undefined 但是通常应该是:
printf '\n\x00\n\n' | function results in: 1
printf 'a\n\n\x00\n' | function results in: 2
将新行数到NUL
或:
printf '\n\x00\n\n' | function results in: 2
printf 'a\n\n\x00\n' | function results in: 1
这是从NUL 计算换行符
或:
printf '\n\x00\n\n' | function results in: 3
printf 'a\n\n\x00\n' | function results in: 3
即忽略任何“尾随”NUL,只要它们位于尾随 NULs 之前、之中或之后
或:
报错
【问题讨论】:
-
我尝试使用 sed 进行一些操作,例如删除所有不尾随换行符的行并计算剩余的行,但无法使其正常工作。
-
如果数据是“可能是二进制的”,你将如何区分合法的
0x0A和换行符? -
@JimGarrison 你认为他们可以通过什么方式来区分?
-
不会有任何区别。任何 \n 都将被视为换行符。
-
@EdMorton 在复制和粘贴过程中出现拼写错误。已更正。