在 awk 中使用 tr 命令用竖线替换正斜杠
Using tr command in awk to replace forward slash with vertical bar
我有一个大文件,其中包含一些类似于以下内容的行:
>m160505_c100980652550000001823221307061611/31156/269-572
我需要用竖线替换所有正斜杠。我认为 awk 是实现此目的的好方法 - 它快速且简单。但是,我不确定如何合并 tr 和 |进入命令。到目前为止,我有以下内容,但我需要帮助来更正它。
awk '/^>/{tr{/}{|}; next}{print}' < Old.fasta > New.fasta
我不反对为此编写脚本,但我觉得 awk 可能是更快的方法。
谢谢
sed
这里可能是最简单的:
$ sed '/^>/ s/\//|/g' <<<'>m160505_c100980652550000001823221307061611/31156/269-572'
>m160505_c100980652550000001823221307061611|31156|269-572
匹配行首的 >
后 (^
) - 正则表达式包含在(强制)定界符 /.../
,[=30= 中]
s/\//|/g
将 (s
) 替换为 |
每个 (g
) /
(转义为 \/
, 因为 /
用作正则表达式定界符)。
为清楚起见,使用备用分隔符 @
:sed s'/^>/ s@/@|@g'
。
一个与单独的 tr
实用程序类似的变体,使用 sed
的 y
函数:
sed '/^>/ y/\//|/' <<<'>m160505_c100980652550000001823221307061611/31156/269-572'
- 函数
y
将第一个参数 中的任何字符单独 替换为第二个参数中的 对应 字符 - 请注意这意味着第一个和第二个参数必须具有相同的长度(tr
不需要这个)。
awk
没有 tr
command/function,也没有 easy 方法来获得相同的效果。既然你标记了这个 "perl",我假设你也对 perl oneliner 持开放态度:
perl -lpe '/^>/ and tr{/}{|}' < Old.fasta > New.fasta
做与 awk 看起来正在尝试做的相同的事情;在以 >
.
开头的行上将所有 /
替换为 |
$ awk '/^>/{gsub("/","|")}1' file
>m160505_c100980652550000001823221307061611|31156|269-572
如果您确实需要 awk 中的 tr() 函数,则必须编写它,例如:
$ cat tr.awk
function tr(oldStr,oldList,newList, newStr,i,o2n,chr) {
for (i=1; i<=length(oldList); i++) {
o2n[substr(oldList,i,1)] = substr(newList,i,1)
}
for (i=1; i<=length(oldStr); i++) {
chr = substr(oldStr,i,1)
newStr = newStr (chr in o2n ? o2n[chr] : chr)
}
return newStr
}
{ print [=11=], "->", tr([=11=],"xyz","123") }
$ echo 'axbyczd' | awk -f tr.awk
axbyczd -> a1b2c3d
我有一个大文件,其中包含一些类似于以下内容的行:
>m160505_c100980652550000001823221307061611/31156/269-572
我需要用竖线替换所有正斜杠。我认为 awk 是实现此目的的好方法 - 它快速且简单。但是,我不确定如何合并 tr 和 |进入命令。到目前为止,我有以下内容,但我需要帮助来更正它。
awk '/^>/{tr{/}{|}; next}{print}' < Old.fasta > New.fasta
我不反对为此编写脚本,但我觉得 awk 可能是更快的方法。 谢谢
sed
这里可能是最简单的:
$ sed '/^>/ s/\//|/g' <<<'>m160505_c100980652550000001823221307061611/31156/269-572'
>m160505_c100980652550000001823221307061611|31156|269-572
匹配行首的
>
后 (^
) - 正则表达式包含在(强制)定界符/.../
,[=30= 中]s/\//|/g
将 (s
) 替换为|
每个 (g
)/
(转义为\/
, 因为/
用作正则表达式定界符)。
为清楚起见,使用备用分隔符 @
:sed s'/^>/ s@/@|@g'
。
一个与单独的 tr
实用程序类似的变体,使用 sed
的 y
函数:
sed '/^>/ y/\//|/' <<<'>m160505_c100980652550000001823221307061611/31156/269-572'
- 函数
y
将第一个参数 中的任何字符单独 替换为第二个参数中的 对应 字符 - 请注意这意味着第一个和第二个参数必须具有相同的长度(tr
不需要这个)。
awk
没有 tr
command/function,也没有 easy 方法来获得相同的效果。既然你标记了这个 "perl",我假设你也对 perl oneliner 持开放态度:
perl -lpe '/^>/ and tr{/}{|}' < Old.fasta > New.fasta
做与 awk 看起来正在尝试做的相同的事情;在以 >
.
/
替换为 |
$ awk '/^>/{gsub("/","|")}1' file
>m160505_c100980652550000001823221307061611|31156|269-572
如果您确实需要 awk 中的 tr() 函数,则必须编写它,例如:
$ cat tr.awk
function tr(oldStr,oldList,newList, newStr,i,o2n,chr) {
for (i=1; i<=length(oldList); i++) {
o2n[substr(oldList,i,1)] = substr(newList,i,1)
}
for (i=1; i<=length(oldStr); i++) {
chr = substr(oldStr,i,1)
newStr = newStr (chr in o2n ? o2n[chr] : chr)
}
return newStr
}
{ print [=11=], "->", tr([=11=],"xyz","123") }
$ echo 'axbyczd' | awk -f tr.awk
axbyczd -> a1b2c3d