我有一个很大的文本文件,它基本上是一个数据流,每一行几乎都压缩在一起。我被要求调查某些列中某些数据的失败。数据不以任何方式分隔。不过,我确实有一个“列”长度列表以及关于每个“列”中是否有相关数据的评论。
我会使用 Excel,但 Excel 按列分隔的限制为每行 1000 个字符,而每行远远超出此范围。其中许多字段都有 30 个空格的字符串作为填充符,并且至少有 15 个左右......我希望解析这些指定的“空”字段。
我需要的是一种可以输入文件的方法,并使用我可以提供的数组,该数组具有列长度,也许还有一个像“X”这样的标记来忽略我想要忽略的相应列,让它吐出一个新的带有分隔符的文件,然后我可以将其反馈到 Excel 中进行分析。
例如,如果我有一个包含一行的文件aaaaaabbbbbccccdddddeeeffffff
,我将这个文件与一个数组一起输入,它会在该行中[6 5 4X 5 3X 6]
吐出一个文件。aaaaaa^bbbbb^ddddd^ffffff
有没有办法可以用grep
,awk
或 来完成此操作sed
?
提前致谢。
答案1
短的cut
命令方式:
样本input.txt
内容:
aaaaaabbbbbccccdddddeeeffffff
wwwwwwddddd111133333xxxaaaaaa
ffffff00000sssszzzzz000rrrrrr
工作:
cut -c 1-6,7-11,16-20,24-29 --output-delimiter=^ input.txt
-c
- 仅选择字符1-6,7-11,16-20,24-29
- 字符位置连续范围,灵活可调--output-delimiter=^
- 输出字段分隔符,您可以将其调整为您想要的任何内容
输出:
aaaaaa^bbbbb^ddddd^ffffff
wwwwww^ddddd^33333^aaaaaa
ffffff^00000^zzzzz^rrrrrr
答案2
如果您有 GNU awk,您可以指定显式字段宽度,例如
$ printf 'aaaaaabbbbbccccdddddeeeffffff\n' |
gawk -v FIELDWIDTHS="6 5 4 5 3 6" -v OFS="^" '{print $1, $2, $4, $6}'
aaaaaa^bbbbb^ddddd^ffffff
从版本 4.2 开始,您可以使用语法跳过字符n:m
,例如
printf 'aaaaaabbbbbccccdddddeeeffffff\n' |
gawk -v FIELDWIDTHS="6 5 4:5 3:6" -v OFS="^" '{$1=$1} 1'
aaaaaa^bbbbb^ddddd^ffffff
(仅强制使用指定的字段宽度$1=$
重新评估)。$0
答案3
如果没有看到您的确切输入和所需的输出,很难说,但是......
sed -e "$(
printf '%d\n' 6 5 4 5 3 6 |
awk '
{
f[NR] = f[NR-1] + $1
}
END {
for (i=NR; i>0; i--) {
printf "s/./&^/%d\n", f[i]
}
}
'
)" infile.txt | cut -d^ -f1,2,4,6
未经测试。没有错误,我保证。 ;)
好的,我测试过。我错过了最后的大括号END
。没有其他错误。在示例输入上完美运行。输出是:
aaaaaa^bbbbb^ddddd^ffffff
答案4
改进版本罗曼·佩雷克雷斯特的cut
回答,带有列数组解析器,包括X
后缀以显示要跳过多少列。
加载 array $n
,并创建一个函数将数组解析为数字cut -c
:
n=(6 5 4X 5 3X 6)
col_array() { j=$(h=0;
for f in $@; do
g=${f/[Xx]};
i=$((h+1));
h=$((h+g));
[ $g = $f ] && echo -n $i-$h,
done;) ;
echo ${j%,}; }
文件输入.txt包含:
aaaaaabbbbbccccdddddeeeffffff
wwwwwwddddd111133333xxxaaaaaa
ffffff00000sssszzzzz000rrrrrr
col_array()
与以下一起使用cut
:
cut -c $(col_array ${n[@]}) --output-delimiter=^ input.txt
输出:
aaaaaa^bbbbb^ddddd^ffffff
wwwwww^ddddd^33333^aaaaaa
ffffff^00000^zzzzz^rrrrrr
并不严格需要数组,因为col_array()
会解析它的参数:
cut -c $(col_array 3 5X 7) --output-delimiter=^ input.txt
输出:
aaa^bbbcccc
www^ddd1111
fff^000ssss