重新排序文本文件中的大量列

时间:2013-06-21 21:02:05

标签: regex perl sed awk pattern-matching

我需要一个方法(awk / perl / sed / shell)来修改文件的内容,如下所示:

在:

123456|ABCDEF|123|011|A|E|NULL|R|UNKNOWN|A1|A2|B1|B2|C1|C2|2013|2013|9999|Y

后:

123456|ABCDEF|123|011|A|E|NULL|R|UNKNOWN|9999|Y|A1|B1|C1|NULL|NULL|NULL|2013|2013

我需要移动第9列之后的最后2列,删除第11,13,15列,并在第14列和第15列(NULL|NULL|NULL)之间插入C1|2013。任何提示赞赏。 cut命令无法更改插入顺序,因此需要采用另一种方式。输入文件有1000万行,我正在寻找最好的方法。

4 个答案:

答案 0 :(得分:4)

丑陋的问题需要丑陋的解决方案:

awk -F"|" '{
    for(i=1;i<=9;i++) { printf "%s|" ,$i }
    printf "%s|%s|",$(NF-1),$NF
    for(i=10;i<16;i+=2) { printf "%s|" ,$i }
    printf "%s|%s|%s|","NULL","NULL","NULL"
    for(i=16;i<(NF-2);i++) { printf "%s|" ,$i }
    print $(NF-2)
}' inputFile

答案 1 :(得分:2)

GNU代码

sed -r 's/((\w+\|){9})(\w+\|)\w+\|(\w+\|)\w+\|(\w+\|)\w+(\|\w+\|)(\w+)\|(\w+\|\w+)/\1\8|\3\4\5NULL|NULL|NULL\6\7/' file

$cat file
123456|ABCDEF|123|011|A|E|NULL|R|UNKNOWN|A1|A2|B1|B2|C1|C2|2013|2013|9999|Y

$sed -r 's/((\w+\|){9})(\w+\|)\w+\|(\w+\|)\w+\|(\w+\|)\w+(\|\w+\|)(\w+)\|(\w+\|\w+)/\1\8|\3\4\5NULL|NULL|NULL\6\7/' file
123456|ABCDEF|123|011|A|E|NULL|R|UNKNOWN|9999|Y|A1|B1|C1|NULL|NULL|NULL|2013|2013

答案 2 :(得分:0)

您可以使用awk

awk 'BEGIN{FS=OFS="|"}{print $1,$2,...,"9999|Y",..."NULL|NULL|NULL",...'

$1是第一个字段,$2是第二个字段,等等。

答案 3 :(得分:0)

不想计算您的列,但您可以从下一个perl脚本中获取想法:

perl -F'/\|/' -lanE 'say join("|", $F[2], "NULL", "NULL", $F[0], $F[3], $F[1])'

输入

123456|ABCDEF|123|011

产生

123|NULL|NULL|123456|011|ABCDEF

tha autosplit模式会分割|字符上的每一行,您可以根据需要重新排序字段。 join|一起加入字段。

为了好玩 - 纯粹的bash - 并且缓慢:)

while IFS='|' read -r a b c d
do
echo "$a|NULL|$d|$c|NULL|$b"
done << EOF
123456|ABCDEF|123|011
EOF

打印

123456|NULL|011|123|NULL|ABCDEF