Bash-向文件中的特定位置添加值

Bash-向文件中的特定位置添加值,bash,sed,Bash,Sed,对于以10开头的所有行,无论行的长度如何,我都需要将值a1添加到位置10-12。如果位置10-12中存在值,则它们应被值A1覆盖 我尝试了以下方法: sed -i 's/.\{9\}/&A 1/' FILE 但是,这给了我两个问题 值“A 1”将添加到所有行,而不仅仅是从10开始的行 如果行的长度则该值不会打印到行中,这对于sed很难做到,因为它需要一些计数。您可以使用Perl: perl -lpe 'if(/^10/){ $_ = sprintf("%-12s",$_); s/(.{

对于以
10
开头的所有行,无论行的长度如何,我都需要将值
a1
添加到位置10-12。如果位置10-12中存在值,则它们应被值
A1
覆盖

我尝试了以下方法:

sed -i 's/.\{9\}/&A 1/' FILE
但是,这给了我两个问题

  • 值“A 1”将添加到所有行,而不仅仅是从10开始的行

  • 如果行的长度则该值不会打印到行中,这对于sed很难做到,因为它需要一些计数。您可以使用Perl:

    perl -lpe 'if(/^10/){ $_ = sprintf("%-12s",$_); s/(.{9}).../$1A 1/;};' input
    
    和bash脚本版本:

    while read line; do
        echo "$(printf "%-12s" "$line" | sed 's/^\(10.\{7\}\).../\1A 1/')"
    done < input
    
    sed-i的/\(10.\{0,8\\\)\{0,2\\\(.*)/\1A 1\2/'文件
    几乎可以工作,唯一的问题是如果行少于10个字符,它就不会填充它

    结果:

    $ sed 's/\(10.\{0,8\}\)\.\{0,3\}\(.*\)/\1A 1\2/' test.txt 
    01SAGHSUIGAUGB    
    02AWRHGAWRUIGH    
    10H    A 1
    02DFHAliffh    
    10shaofgvaA 1suioghsfag    
    02GAQTHEGHQ    
    10FGHOHGFRA 1T    
    90AIRLGBA
    
    {0,8}也可以写入。{,8}匹配长度为0-8个字符的任何字符序列,括号用于对匹配的模式进行分组,然后可以在子替换中由\1和\2引用。如果您有更多的组,您可以使用\3\4等来引用它们


    正如其他人所指出的,您可以先填充行,以确保将
    a1
    放在正确的列中,但随后您需要使用sed以外的其他内容使用您自己的解决方案,只需进行2个小的修改

  • 首先,为每行添加10个空格,这样短行就不会有问题
  • 仅将编辑应用于以“10”开头的行
  • x
    表示上面的空格

    这将很好地工作:

    awk '/^10/{$0=$0 "          ";q=substr($0,1,9);r=substr($0,13); $0=q "A 1" r} {sub(/ *$/,x);print}' t
    01SAGHSUIGAUGB
    02AWRHGAWRUIGH
    10H      A 1
    02DFHAliffh
    10shaofgvA 1ioghsfag
    02GAQTHEGHQ
    10FGHOHGFA 1
    90AIRLGBA
    
    更改如果从10开始,尝试按
    a1
    更改如果字符串大于12个字符,如果失败,请添加足够的空间以达到9个字符,然后添加
    a1

    这可能适合您(GNU-sed):


    如有必要,请在行中填充空格,然后将字符10-12替换为
    a1

    ,以便在
    10H
    之后添加空格,以在正确的位置获得
    a1
    ?是的,这绝对正确!你需要一个起锚。您还需要删除最后的
    *
    ,以防止截断行的其余部分。谢谢。我故意截断了行的其余部分,因为我没有看到大于12个字符的示例。我已经输入了我的答案。这不会在10小时后增加额外的空间,因此
    A 1
    不在正确的位置。这会匹配超过12个字符的行吗?TOP没有指定行的最大长度,也没有指定在位置12Hi之后如何处理字符,所以接近但没有cigarr。在我提供的示例中,它非常有效。但是,我正在更改的值实际上位于pos 575-613,它给出了一个reg exp错误:在regex m/(它在我的机器上运行良好。你用10个空格替换了XXXXXXXXX吗?你得到了什么输出?我得到这个
    10H
    应该是
    10H a1
    (Ubuntu 12.04)(6
    H
    A
    01SAGHSUIGAUGB    
    02AWRHGAWRUIGH    
    10H      A 1
    02DFHAliffh    
    10shaofgvA 1ioghsfag    
    02GAQTHEGHQ    
    10FGHOHGFA 1   
    90AIRLGBA
    
    $ sed 's/\(10.\{0,8\}\)\.\{0,3\}\(.*\)/\1A 1\2/' test.txt 
    01SAGHSUIGAUGB    
    02AWRHGAWRUIGH    
    10H    A 1
    02DFHAliffh    
    10shaofgvaA 1suioghsfag    
    02GAQTHEGHQ    
    10FGHOHGFRA 1T    
    90AIRLGBA
    
    sed -e 's/$/xxxxxxxxxx/' -e '/^10/s/.\{9\}/&A 1/' test.txt
    
    awk '/^10/{$0=$0 "          ";q=substr($0,1,9);r=substr($0,13); $0=q "A 1" r} {sub(/ *$/,x);print}' t
    01SAGHSUIGAUGB
    02AWRHGAWRUIGH
    10H      A 1
    02DFHAliffh
    10shaofgvA 1ioghsfag
    02GAQTHEGHQ
    10FGHOHGFA 1
    90AIRLGBA
    
    sed '/^10/ {
       s/^\(.\{9\}\).../\1A 1/
       t
       s/$/        /
       s/^\(.\{9\}\).*/\1A 1/
       }' YourFile
    
    sed -r '/^10/{:a;s/^.{,11}$/& /;ta;s/^(.{9}).../\1A 1/}' file