如何将两个awk文件合并为一个?

时间:2017-04-04 13:55:00

标签: bash awk

这是一个原始的awk文件,我想格式化它。

输入内容----名为test.txt的原始awk文件

awk 'BEGIN {maxlength = 0}\
     {\
           if (length($0) > maxlength) {\
                maxlength = length($0);\
                longest = $0;\
           }\
     }\
     END   {print longest}' somefile

预期输出----格式良好的awk文件

awk 'BEGIN {maxlength = 0}                      \
     {                                          \
           if (length($0) > maxlength) {        \
                maxlength = length($0);         \
                longest = $0;                   \
           }                                    \
     }                                          \
     END   {print longest}' somefile

步骤1:获取最长的行和字符数

step1.awk

#! /usr/bin/awk 
BEGIN {max =0 }
{
    if (length($0) > max) { max = length($0)}
}
END {print max}

awk -f step1.awk test.txt

现在所有行的最大长度为50。

step2将\置于50 + 2 = 52的位置。

step2.awk

#! /usr/bin/awk
{
if($0 ~ /\\$/){
    gsub(/\\$/,"",$0);
    printf("%-*s\\\n",n,$0);
    }
else{
    printf("%s\n",$0);
    }
}

awk -f step2.awk -v n = 52 test.txt> well_formatted.txt

如何将step1和step2合并为一步,并将step1.awk和step2.awk合并为一个awk文件?

4 个答案:

答案 0 :(得分:4)

更好的版本,您可以使用sub()代替gsub(),并避免两次测试相同的正则表达式sub(/\\$/,""){ ... }

awk 'FNR==NR{ 
             if(length>max)max = length 
             next
     }
     sub(/\\$/,""){
             printf "%-*s\\\n", max+2, $0
             next
     }1' test.txt test.txt

<强>解释

awk 'FNR==NR{                             # Here we read file and will find, 
                                          # max length of line in file
                                          # FNR==NR is true when awk reads first file

             if(length>max)max = length   # find max length 
             next                         # stop processing go to next line
     }
     sub(/\\$/,""){                       # Here we read same file once again, 
                                          # if substitution was made for the regex in record then

             printf "%-*s\\\n", max+2, $0 # printf with format string max+2
             next                         # go to next line
     }1                                   # 1 at the end does default operation print $0, 
                                          # nothing but your else statement printf("%s\n",$0) in step2 
     ' test.txt test.txt

您没有向我们展示,您的输入和预期输出是什么,有一些假设,

如果您的输入如下所示

akshay@db-3325:/tmp$ cat f
123      \
\
12345     
123456   \
1234567  \
123456789 
12345    

您的输出如下

akshay@db-3325:/tmp$ awk 'FNR==NR{ if(length>max)max = length; next}
sub(/\\$/,"",$0){ printf "%-*s\\\n",max+2,$0; next }1' f f
123         \
            \
12345     
123456      \
1234567     \
123456789 
12345  

答案 1 :(得分:1)

awk '
   # first round 
   FNR == NR {
      # take longest (compare and take longest line by line)
      M = M < (l = length( $0) ) ? l : M
      # go to next line
      next
      }

   # for every line of second round (due to previous next) that finish by /
   /[/]$/ {          
      # if a modification is needed
      if ( ( l = length( $0) ) < M ) {
         # add the missing space (using sprintf "%9s" for 9 spaces)
         sub( /[/]$/, sprintf( "%" (M - l) "s/", ""))
         }
      }
  # print all line [modified or not] (7 is private joke but important is <> 0 )
  7
  ' test.txt test.txt

注意:

  • 两端文件必须是两次读取文件
  • 假设最后没有任何东西/(没有空格)。可以很容易地适应但不是目的
  • 假设没有/的行未被修改但仍然打印

答案 2 :(得分:1)

这是一个GNU awk。两次运行,第一次查找最大长度,第二次查找输出。 FS设置为"",以便每个字符都显示在其字段上,最后一个字符将显示在$NF中:

$ awk 'BEGIN{FS=OFS=""}NR==FNR{m=(m<NF?NF:m);next}$NF=="\\"{$NF=sprintf("% "m-NF+2"s",$NF)}1' file file

输出:

awk 'BEGIN {maxlength = 0}               \
     {                                   \
           if (length($0) > maxlength) { \
                maxlength = length($0);  \
                longest = $0;            \
           }                             \
     }                                   \
     END   {print longest}' somefile

说明:

BEGIN     { FS=OFS="" }                         # each char on different field
NR==FNR   { m=(m<NF?NF:m); next }               # find m ax length
$NF=="\\" { $NF=sprintf("% " m-NF+2 "s",$NF) }  # NF gets space padded
1                                               # output

如果您希望\离代码更远,请更改2中的sprintf以符合您的喜好。

答案 3 :(得分:0)

也许是这样的?

wc -L test.txt | cut -f1 -d' ' | xargs -I{} sed -i -e :a -e 's/^.\{1,'{}'\}$/& /;ta' test.txt && sed -i -r 's/(\\)([ ]*)$/\2\1/g' test.txt