Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Awk 对于每一列,如何仅从行中的第一个单词中删除特定字符?_Awk_Sed_Append_Character - Fatal编程技术网

Awk 对于每一列,如何仅从行中的第一个单词中删除特定字符?

Awk 对于每一列,如何仅从行中的第一个单词中删除特定字符?,awk,sed,append,character,Awk,Sed,Append,Character,存档: 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 Scaf

存档:

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

此awk一衬板应能完成以下工作:

awk '{gsub(/_/,"",$1)}1' input.txt
输出:

1 34566 34765 
2 45678 45789
Scaffold3 34567 34799
ScaffoldX 67895 66900
ScaffoldY 34567 34890

使用下划线作为字段分隔符(-F),而不是默认的空白:

awk -F'_' '{print $1$2}' file.txt

我稍微修改了您的输入文件,以演示仅删除第一列中的下划线:

13456634765
2 45678 45_789
脚手架3 345 67 34799
脚手架×678×95 66900
脚手架Y 345 U 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
该命令使用替换。我们匹配所有既不是空格也不是下划线的字符并捕获它们:
\([^\u]*\)
。此表达式锚定在字符串的开头(第一个
^
),后跟下划线

然后,我们用捕获的内容替换它,但去掉下划线(替换字符串中的
\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
    
    这是第二种方法的实现:

    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\u ffold\u Y 345\u 67 34890$
    ^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^
    新col 1旧完整生产线
    
    我们通过巧妙地捕获和替换以下内容,将旧的第一列替换为新的第一列:

    ScaffoldY\nSca\u ffold\u Y 345\u 67 34890$
    ^^^^^^^^^             ^^^^^^^^^^^^^
    \1                      \2
    
    对于一个如下所示的输入文件

    13456634765
    2 45678 45_789
    Sca_ffold_3345_67 34799
    Sca_ffold_X 678_95 66900
    Sca_ffold_Y 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 
    

    这也会替换第一列以外的列中的下划线。没错,我是在假设其他列只包含数字的情况下工作的。一个冒险的假设。非常感谢!我想我学到了一些东西。我将尝试将这种教育应用到我想做的其他替代品中。@everestial007的一个学习可能是使用awk更简单;)嗨,@Benjamin W.:但是,不幸的是,这只在列之间用空格分隔时才起作用。当它们分开时不工作。请参阅输出:1 34566 34765 2 45678 45789脚手架3 345_67 34799脚手架x 678_95 66900脚手架345_6734890@everestial007将括号表达式中空格的所有实例替换为
    [:blank://code>,如
    sed'h/s^\([^[:blank:][]*\)…
    -这包括空格和制表符。@everestial007请参见答案末尾的备注。