我有一个文件 bla.tsv (FS = \t
):
>hCoV-19/xxx/xxx-YYY/xxx
>hCoV-19/xxx/xxx-ZZZ/xxx
精确 :
- 如果真的写了一个字符,那是因为它会按原样出现在每一行中
- 如果一个字符被写成xxx,这是因为它会出现,但每行之间不同(即它可能是一组字母或数字或其他)
- 字符 YYY 和 ZZZ 是我感兴趣的模式,可以是数字或字母
我想转换文件以获得一个新列:
YYY >hCoV-19/xxx/xxx-YYY/xxx
ZZZ >hCoV-19/xxx/xxx-ZZZ/xxx
我知道我必须找到一个在第三个之后匹配的正则表达式/
并返回到上一个-
,但经过多次尝试后我还没有找到它https://regexr.com/
。您知道如何执行正则表达式以及如何将结果放入第一列吗?谢谢
答案1
$ cat file
>hCoV-19/xxx/xxx-YYY/xxx
>hCoV-19/xxx/xxx-ZZZ/xxx
$ awk -F '[/-]' '{ printf "%s %s\n", $5, $0 }' file
YYY >hCoV-19/xxx/xxx-YYY/xxx
ZZZ >hCoV-19/xxx/xxx-ZZZ/xxx
上面的代码awk
将数据视为分为 或 上的字段的/
行-
。第五个这样的字段是您想要添加到每行前面的字段,这就是该printf
语句的作用。
如果-
不是一个好的分隔符(例如,如果第一个斜杠之前的字符串有时不包含破折号,则不是一个好的分隔符),则仅用/
作分隔符,将第三个斜杠分隔的字段拆分为-
,并在前面添加结果的第二位到该行:
$ awk -F / '{ split($3,a,"-"); printf "%s %s\n", a[2], $0 }' file
YYY >hCoV-19/xxx/xxx-YYY/xxx
ZZZ >hCoV-19/xxx/xxx-ZZZ/xxx
使用sed
:
$ sed 's/.*-\([^/]*\).*/\1 &/' file
YYY >hCoV-19/xxx/xxx-YYY/xxx
ZZZ >hCoV-19/xxx/xxx-ZZZ/xxx
或者,如果您使用的是 Plan9 或使用的 Plan9sed
实现存在/
括号表达式内部问题,请为该s///
命令使用一组替代分隔符:
$ sed 's,.*-\([^/]*\).*,\1 &,' file
YYY >hCoV-19/xxx/xxx-YYY/xxx
ZZZ >hCoV-19/xxx/xxx-ZZZ/xxx
这里使用的正则表达式捕获该行/
最后一个字符之后不包含任何字符的子字符串-
。然后它在该行前面添加捕获的子字符串和一个空格。
sed
请注意,该解决方案与awk
前面的解决方案之间的主要区别在于,awk
代码使用了每行的类似字段的结构,而代码则sed
更加“马虎”,只是在破折号后查找一串非斜杠字符。
该https://regexr.com/
站点当前支持 JavaScript 正则表达式和 Perl 兼容正则表达式 (PCRE)。您在这里没有使用这两种语言中的任何一种,因此无论网站告诉您什么,都可能行不通。 awk
使用 POSIX 扩展正则表达式 (ERE),并且大多数其他用于文本操作的标准 Unix 工具(包括sed
)使用 POSIX 基本正则表达式 (BRE)。