awk perl 在新行中复制第一列

awk perl 在新行中复制第一列

我使用 bash 我有这样的表

001_1_174    [g/n                         474536         482492          
mo[g/n                    482492         504062          
'er/                      504062         517352          
ruze                      517352         529562                  
001_1_400    uz[`f                         960192        966656           
.ire                      966656         984416           
tuf/[                     984416         1006166

我想将第一行的字符串(仅包含数字和下划线)复制到其他行,直到另一个数字并对下一个数字执行此操作

像这样

001_1_174    [g/n                    474536         482492           
001_1_174  mo[g/n                    482492         504062           
001_1_174  'er/                      504062         517352           
001_1_174  ruze                      517352       529562                  
001_1_400    uz[`f                   960192        966656           
001_1_400   .ire                      966656         984416           
001_1_400   tuf/[                     984416         1006166

答案1

使用 Perl,如果您喜欢单行代码:

$ perl -pe 'if (/^\s*([\d_]+)/) {$x=$1} else {$_="$x $_"}' input.txt

否则,作为脚本:

use warnings;
use strict;

my $prefix;
while (<>) {
    if ( /^\s*([\d_]+)/ )
        { $prefix = $1 }
    else { $_ = "$prefix $_" }
    print;
}

两者输出:

001_1_174    [g/n                         474536         482492          
001_1_174 mo[g/n                    482492         504062          
001_1_174 'er/                      504062         517352          
001_1_174 ruze                      517352         529562                  
001_1_400    uz[`f                         960192        966656           
001_1_400 .ire                      966656         984416           
001_1_400 tuf/[                     984416         1006166

正则表达式基于您的规范“仅包含数字和下划线”,并且我允许在该行的开头有空格(\s*如果您不想要,请删除)。另外,这将不是如果读取的第一行不以数字开头,则可以正常工作!

答案2

$ awk 'NF == 4 { col1 = $1; print; next } { print col1, $0 }' file
001_1_174    [g/n                         474536         482492
001_1_174 mo[g/n                    482492         504062
001_1_174 'er/                      504062         517352
001_1_174 ruze                      517352         529562
001_1_400    uz[`f                         960192        966656
001_1_400 .ire                      966656         984416
001_1_400 tuf/[                     984416         1006166

首先检测输入行上是否有四列。如果存在,则将该col1变量设置为第一列中的值,按原样打印该行,并且脚本继续输入下一行。否则,将打印该行,但将值col1插入到原始第一列之前。

仅当看似随机的乱码不包含任何空白字符时,这才有效。如果是这样,您可能必须使用-F 'delimiter'delimiter其中 是列之间使用的分隔符(例如'\t'制表符)。

它还假设第一行有四列,否则col1该行的变量将保持未设置状态。


实施评论中的建议用户CAS,这使得它与输入数据中的列数无关(它只是假设第一行包含包含特殊第一列的任何行的正确列数):

$ awk 'NR == 1 { cols = NF } NF == cols { col1 = $1; print; next } { print col1, $0 }' file
001_1_174    [g/n                         474536         482492
001_1_174 mo[g/n                    482492         504062
001_1_174 'er/                      504062         517352
001_1_174 ruze                      517352         529562
001_1_400    uz[`f                         960192        966656
001_1_400 .ire                      966656         984416
001_1_400 tuf/[                     984416         1006166

答案3

最短的awk

awk 'NF < 4{ $0=n OFS $0 }{ n=$1 }1' file

输出:

001_1_174    [g/n                         474536         482492          
001_1_174 mo[g/n                    482492         504062          
001_1_174 'er/                      504062         517352          
001_1_174 ruze                      517352         529562                  
001_1_400    uz[`f                         960192        966656           
001_1_400 .ire                      966656         984416           
001_1_400 tuf/[                     984416         1006166

要依赖特定的字段格式,您可以使用以下内容更改上述内容:

awk 'NF<4{ $0=n OFS $0 }$1~/^[0-9_]+$/{ n=$1 }1' file

相关内容