文件输入:
1 34566 34765
2 45678 45789
Scaffold_3 34567 34799
Scaffold_X 67895 66900
Scaffold_Y 34567 34890
注意:有很多行。我想从第一列中的单词中仅删除下划线(_
)。除此之外不应该有其他变化。我正在学习sed和awk所以使用这些工具的任何命令都会有所帮助。此外,解释也会有所帮助。
归档:
1 34566 34765
2 45678 45789
Scaffold3 34567 34799
ScaffoldX 67895 66900
ScaffoldY 34567 34890
答案 0 :(得分:7)
这个awk单行应该做的工作:
awk '{gsub(/_/,"",$1)}1' input.txt
输出:
1 34566 34765
2 45678 45789
Scaffold3 34567 34799
ScaffoldX 67895 66900
ScaffoldY 34567 34890
答案 1 :(得分:2)
我稍微修改了您的输入文件,以证明只删除了第一列中的下划线:
1 34_566 34765
2 45678 45_789
Scaffold_3 345_67 34799
Scaffold_X 678_95 66900
Scaffold_Y 345_67 34890
至于删除下划线,我使用了sed:
$ sed 's/^\([^ _]*\)_/\1/' infile
1 34_566 34765
2 45678 45_789
Scaffold3 345_67 34799
ScaffoldX 678_95 66900
ScaffoldY 345_67 34890
该命令使用替换。我们匹配所有既不是空格也不是下划线的字符并捕获它们:\([^ _]*\)
。此表达式锚定在字符串的开头(第一个^
),后跟一个下划线。
然后我们用我们捕获的内容替换它,但保留下划线(替换字符串中的\1
反向引用)。
如果第一列中有多个下划线,那么sed会有点棘手。基本上有两种选择:
以下是第一种方法的实施:
sed '
:a # Label to jump to
s/^\([^ _]*\)_/\1/ # Replace underscore in first column (like above)
ta # Jump to label if something was changed
' infile
这是第二种方法的实施:
sed '
h # Copy pattern space to hold space
s/^\([^ ]*\).*/\1/ # Remove everything but the first column
s/_//g # Delete all underscores
G # Append hold space to pattern space
# Replace old first column with underscore-free first column
s/^\(.*\)\n[^ ]*\(.*\)/\1\2/
' infile
最后一步是最棘手的一步。在它之前,我们的模式空间看起来像这样(假设第一列中有多个下划线的输入文件):
ScaffoldY\nSca_ffold_Y 345_67 34890$
^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
New col 1 Old complete line
我们通过智能捕获和替换来替换旧的第一列和新的第一列:
ScaffoldY\nSca_ffold_Y 345_67 34890$
^^^^^^^^^ ^^^^^^^^^^^^^
\1 \2
因此对于看起来像
的输入文件1 34_566 34765
2 45678 45_789
Sca_ffold_3 345_67 34799
Sca_ffold_X 678_95 66900
Sca_ffold_Y 345_67 34890
我们得到这样的输出(将命令压缩成一行):
$ sed 'h;s/^\([^ ]*\).*/\1/;s/_//g;G;s/^\(.*\)\n[^ ]*\(.*\)/\1\2/' infile
1 34_566 34765
2 45678 45_789
Scaffold3 345_67 34799
ScaffoldX 678_95 66900
ScaffoldY 345_67 34890
请注意,如果输入文件没有空格分隔,则无法正常工作。必须改变括号表达式中的空格以反映例如制表符分隔。第一个解决方案变为
sed 's/^\([^[:blank:]_]*\)_/\1/' infile
第二个
sed ':a;s/^\([^[:blank:]_]*\)_/\1/;ta' infile
和第三个
sed 'h;s/^\([^[:blank:]]*\).*/\1/;s/_//g;G;s/^\(.*\)\n[^[:blank:]]*\(.*\)/\1\2/' infile
答案 2 :(得分:0)
使用下划线作为字段分隔符(-F)而不是默认的空格:
awk -F'_' '{print $1$2}' file.txt