我有以下数据表:
ssh 22/tcp 0.182286 # Secure Shell Login
linuxconf 98/tcp 0.000088
tacnews 98/udp 0.000560 # TAC News
我希望从中生成以下格式的 CSV 文件:
ssh,22,tcp,Secure Shell Login
linuxconf,98,tcp,
tacnews,98,udp,Tac News
我将丢弃小数十进制数,并包含不带“#”的描述(如果存在)。
我将数据视为一堆字段(原谅人造正则表达式):
^{1}\s+{2}/{3}\s+{4}\s+# {5}$
为此我将输出:
{1},{2},{3},{5}
执行此操作最简单且最合适的工具是什么?我将不胜感激在语法方面的帮助来实现这一目标。
答案1
解决此类问题的最佳工具可能是sed
,这是一个使用扩展正则表达式的工作示例:
sed -E 's:^([^ ]*)\s+([^/]*)/([^ ]*)\s+[^ ]*\s*#?\s*(.*):\1,\2,\3,\4:' file
或者,如果您的输入可能是制表符分隔的:
sed -E 's:^([^[:space:]]*)\s+([^/]*)/([^[:space:]]*)\s+[^[:space:]]*\s*#?\s*(.*):\1,\2,\3,\4:' file
输出:
ssh,22,tcp,Secure Shell Login
linuxconf,98,tcp,
tacnews,98,udp,TAC News
解释
s:::
使用冒号作为表达式分隔符^([^ ]*)
第一个捕获组,匹配行开头的非空格字符序列\s+
忽略空间([^/]*)
第二个捕获组,匹配斜线/
忽略斜杠([^ ]*)
第三个捕获组,匹配非空格字符序列\s+
忽略空间[^ ]*
忽略小数\s*#?\s*
忽略空格和可选哈希(.*)
第四个捕获组,该行的其余部分
答案2
我会使用 perl:你已经勾勒出了正则表达式,这填补了空白。
perl -lne '
/ (\S+) \s+ # non-whitespace followed by whitespace
(\d+) \/ # digits followed by slash
(\S+) \s+ # non-whitespace followed by whitespace
(\S+) \s* # non-whitespace followed by optional whitespace
(?:\#\s)? (.*) # possibly a hash+space and whatever follows
/x and print "$1,$2,$3,$4,$5"' file