繁体   English   中英

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

[英]How to combine the two awk files into one?

这是原始的awk文件,我想对其进行格式化。

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

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:获得最长的行和字符数

第一步

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

awk -f step1.awk test.txt

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

步骤2将\\放在位置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 -vn = 52 test.txt> well_formatted.txt

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

更好的版本,可以使用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  
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

注意:

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

这是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

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

也许是这样的吗?

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM