用于解析单个列中多个行的Shell脚本

时间:2013-04-22 19:29:35

标签: shell unix awk

我正在通过一个非常复杂且冗长的多条件语句来完成这项工作,并且想知道是否有人知道更简单的方法。我有一个我要解析的多列/多行列表。我需要做的是在第5个位置取第一行“ * ”并将所有这些条目复制到接下来几行的空白处,然后丢弃原始的顶行。使这一点复杂化的是,有时接下来的几行在所有其他字段中可能没有空格(参见原始列表的下半部分)。如果是这种情况,我想采取额外的条目(下面的Q1)并将其放在行的末尾,在新列中。

原始列表:

A B C D ***** F G
    E1
    E2
    E3
Q R S T ***** V W
    U1
Q1  U2

最终输出:

A B C D E1 F G
A B C D E2 F G
A B C D E3 F G
Q R S T U1 V W
Q R S T U2 V W Q1

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

简洁/神秘的单线:

awk '/[*]/{f=$0;p="[*]+";next}{r=$2?$2:$1;sub(p,r,f);p=r;print $2?f" "$1:f}' file
A B C D E1 F G
A B C D E2 F G
A B C D E3 F G
Q R S T U1 V W
Q R S T U2 V W Q1

<强>解释

/[*]+/ {                  # If line matches line with pattern to replace
    line = $0             # Store line
    pat="[*]+"            # Store pattern
    next                  # Skip to next line
}
{
    if (NF==2)            # If the current line has 2 fields 
       replace = $2       # We want to replace with the second
    else                  # Else
       replace = $1       # We want to replace with first first

    sub(pat,replace,line) # Do the substitution
    pat=replace           # Next time the pattern to replace will have changed 

    if (NF==2)            # If the current line has 2 fields
       print line,$1      # Print the line with the replacement and the 1st field
    else                  # Else
       print line         # Just print the line with the replacement 
}

要运行脚本,请将其保存到script.awk等文件并运行awk -f script.awk file