我需要一个方法(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万行,我正在寻找最好的方法。
答案 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:
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