-1

我需要一种方法(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 列,并NULL|NULL|NULL在第 14 列和第 15 列之间插入(C1|2013)。任何提示表示赞赏。cut命令不能改变插入的顺序,所以需要换一种方式。输入文件有 1000 万行这样的行,我正在寻找最好的方法来做到这一点。

4

4 回答 4

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
于 2013-06-21T21:21:52.567 回答
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

$猫文件
123456|ABCDEF|123|011|A|E|NULL|R|未知|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/' 文件
123456|ABCDEF|123|011|A|E|NULL|R|UNKNOWN|9999|Y|A1|B1|C1|NULL|NULL|NULL|2013|2013
于 2013-06-21T22:03:54.380 回答
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

thaautosplit模式分割字符上的每一行|,您可以根据需要对字段重新排序。将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
于 2013-06-21T21:30:56.937 回答
0

您可以awk为此使用:

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

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

于 2013-06-21T21:16:24.223 回答