String 如何用“文件”分隔文件\";在Mac上
我有一个文档,其行之间用“\t\n”分隔。记录之间用“\t”或“\n”分隔 通常,这应该是一个straigtforward awk查询:String 如何用“文件”分隔文件\";在Mac上,string,macos,shell,unix,replace,String,Macos,Shell,Unix,Replace,我有一个文档,其行之间用“\t\n”分隔。记录之间用“\t”或“\n”分隔 通常,这应该是一个straigtforward awk查询: BEGIN { RS='\t\n'; } { print; print "Next entry:"; } 但是,在Mac电脑上,正则表达式似乎不受支持(也许我做得不对?),所以我尝试了,RS=“\t\n”;但是,这被解释为RS='\t |\n'。从命令行运行awk时出现类似问题: awk 1 RS='\t\n' ORS='abc' inpu
BEGIN {
RS='\t\n';
}
{
print;
print "Next entry:";
}
但是,在Mac电脑上,正则表达式似乎不受支持(也许我做得不对?),所以我尝试了,RS=“\t\n”
;但是,这被解释为RS='\t |\n'
。从命令行运行awk时出现类似问题:
awk 1 RS='\t\n' ORS='abc' input > output
替换\t
,但保留\n
下一次尝试:使用tr
。对于多个字符的序列,这显然是失败的,因为\t
和\n
都在行中单独使用
下一步:
但是,它不起作用。输入任何ASCII字符序列而不是\t\n都有效
阅读手册。它表示sed字符串中不支持\t
。很公平
sed -e '/\x9\xa/s//abc/' input > output
还是不行。想法:使用tr
将\t
和\n
替换为输入文件中未使用的字符,使用sed
将它们更改为我想要的,然后使用tr
将剩余字符更改回它们应该的状态
tr: Illegal byte sequence
结果是,f6
字符使tr
完全失败
在中仔细阅读了这些建议。这可能适用于替换输出字符串(除了“通过CTRL+V将选项卡粘贴到命令提示符中”的建议——shell刚刚拒绝了该粘贴),但在我的情况下似乎没有帮助
也许是因为它是Mac?也许是因为这是我要找的文本,而不是替换为?可能是与\n
的组合
还有其他建议吗
更新:
我找到了线。显然,我甚至无法使用该线程中的建议将\n
替换为字符串“abc”
编辑:源文件的十六进制头:
5a 20 4e 4f 09 0a 41 53 20 4f 46 20 30 31 2d 30
34 2d 30 35 20 45 4d 50 4c 4f 59 45 45 0a 47 52
4f 55 50 09 48 49 52 45 20 44 41 54 45 09 53 41
4c 41 52 59 09 4a 4f 42 20 54 49 54 4c 45 09 0a
4a 4f 42 20 4c 45 56 45 4c 0a 53 45 52 49 45 53
09 41 50 50 54 20 54 59 50 45 09 0a 50 41 59 20
53 54 41 54 55 53 0a f6
不幸的是,同样在macOS上使用的BSD
awk
,完全不支持多字符记录分隔符(RS
)(与POSIX一致)-只支持单个文字字符
BSDsed
,也用于macOS,只支持正则表达式中的\n
-不支持任何其他转义,包括十六进制转义(例如\x09
)
有关GNU和BSDsed
的综合比较,请参见我的文章
假设您的sed
命令原则上有效,您可以使用
($'\t'
)来拼接文本选项卡字符。在sed
脚本中(假设bash
(macOS默认shell),ksh
,或zsh
):
请注意,为了替换换行符,必须指示
sed
首先将整个文件读入内存,这就是-e':a'-e'$!{N;ba'-e'}'
是(常见GNUSed
idiom:a;$!{N;ba}
)的BSD-Sed兼容形式。你能提供一份“不快乐”文件的副本吗?@MarkSetchell好的,我上传了头。
5a 20 4e 4f 09 0a 41 53 20 4f 46 20 30 31 2d 30
34 2d 30 35 20 45 4d 50 4c 4f 59 45 45 0a 47 52
4f 55 50 09 48 49 52 45 20 44 41 54 45 09 53 41
4c 41 52 59 09 4a 4f 42 20 54 49 54 4c 45 09 0a
4a 4f 42 20 4c 45 56 45 4c 0a 53 45 52 49 45 53
09 41 50 50 54 20 54 59 50 45 09 0a 50 41 59 20
53 54 41 54 55 53 0a f6
sed -e ':a' -e '$!{N;ba' -e '}' -e '/'$'\t''\n/s//NextEntry:/g'