我有一个非常具体的需求,我一直试图解决这个问题,但没有成功。
我有一个日志,它是通过转储tcp / ip套接字创建的......它将Hex转换为ASCII,但自然会有一些特殊字符。
我已设法删除它们,但我目前遇到了一个困难:有时候会发送一个0x0A,这会混淆我的应用程序......我正在尝试将其删除,但之后它也会删除有效行尾的0x0A ......
基本上,我在日志文件中有:
08-14-2017 10:00:00 String={Teste String}
08-14-2017 10:00:00 String={
Teste String2}
08-14-2017 10:00:00 String={
Teste String3}
08-14-2017 10:00:00 String={Teste String4}
我希望最终结果为
08-14-2017 10:00:00 String={Teste String}
08-14-2017 10:00:00 String={Teste String2}
08-14-2017 10:00:00 String={Teste String3}
08-14-2017 10:00:00 String={Teste String4}
字符总是在{}之间,所以}之后的每个0x0A都有效,但内部不是。
我尝试的每个命令都会删除所有0x0A,或者根本不工作。
我尝试过像
这样的事情sed 's/^[^}]*}//'
sed 's/\x0A$//'
任何想法?
答案 0 :(得分:3)
另一个更简单 awk
:
awk '{printf "%s%s", $0, (/}/ ? ORS : "")}' file
08-14-2017 10:00:00 String={Teste String}
08-14-2017 10:00:00 String={Teste String2}
08-14-2017 10:00:00 String={Teste String3}
08-14-2017 10:00:00 String={Teste String4}
这个awk
命令检查一行中是否存在}
,然后只打印换行符,否则打印出不带换行符的记录。
答案 1 :(得分:1)
这对于sed来说当然是可能的,但在awk中更容易阅读和理解:
awk 'BEGIN{ OFS=FS="{"; ORS=RS="}" } { sub(/[^[:print:]]/,"",$2) } 1' input.txt
这是做什么的?
{
,将输入和输出记录分隔符设置为}
。这让我们可以预测地将括号内的文本作为特定字段(至少基于您的示例数据)获取。答案 2 :(得分:1)
使用GNU awk for multi-char RS,我们可以隔离每个{...}
字符串并删除其中的换行符:
$ awk -v RS='{[^}]+}' '{ORS=gensub(/\n/,"","g",RT)}1' file
08-14-2017 10:00:00 String={Teste String}
08-14-2017 10:00:00 String={Teste String2}
08-14-2017 10:00:00 String={Teste String3}
08-14-2017 10:00:00 String={Teste String4}
对于这个特定情况,其他awk答案将正常工作,上面只是一个更通用的解决方案,解决了分隔分隔字符串然后对它执行操作的问题,就像在这种情况下删除字符一样。
答案 3 :(得分:0)
使用sed :
Linux的:
$ sed -r ':a;N;$!ba;s/(\{[^}]*)\\n([^{]*\})/\1\2/g' file
08-14-2017 10:00:00 String={Teste String}
08-14-2017 10:00:00 String={Teste String2}
08-14-2017 10:00:00 String={Teste String3}
08-14-2017 10:00:00 String={Teste String4}
FreeBSD和macOS:
sed -e ':a' -e 'N;$!ba' -e 's/(\{[^}]*)\\n([^{]*\})/\1\2/g' file
<强>说明强>
-e ':a' -e 'N;$!ba'
允许我们在sed的每次迭代中考虑当前行和下一行。有关详细信息,请参阅this SO answer。
(\{[^}]*)
确保有一个开口大括号后面没有结束大括号。
([^{]*\})
则恰恰相反。
答案 4 :(得分:0)
的Perl:
$ perl -0777 -pe 's/({[^}]*)\x0A([^}]*})/\1\2/g' file
08-14-2017 10:00:00 String={Teste String}
08-14-2017 10:00:00 String={Teste String2}
08-14-2017 10:00:00 String={Teste String3}
08-14-2017 10:00:00 String={Teste String4}
Pure Bash(基于anubhava的awk):
while IFS="\n" read -r line; do
le=""
[[ $line =~ \} ]] && le=$'\n'
printf "%s%s" "$line" "$le"
done <file