我有一个数据库,其中有 6037 个以空格分隔的列和 450 行,如下所示:
1807 1452 1598 1 6.655713 A B A B ... 0
1808 1452 1763 1 9.362033 0 0 A B ... A
1809 1452 1527 2 6.728534 A B A A ... B
1810 1452 1367 2 9.4055 A B A A B ... A
... ... ... ... ... ... ... ... ... ...
1812 1452 1258 1 6.363032 0 0 A B ... B
我想要获得一个仅包含前 676 列的新数据库。
最好是使用某种形式awk
或sed
命令。
答案1
如果文件中的列分隔符是单个字符(例如空格),cut
则可以轻松做到这一点:
cut -d' ' -f-676 <in >out
这将仅打印从第一列到第 676 列以空格分隔的列。
如果您需要将每个空格字符都算作分隔符,则sed
解决方案是:
sed -r 's/\s+\S+//677g' <in >out
这将从第 677 列开始的每一列(= 至少一个空格字符,后面跟着至少一个非空格字符)都替换为空。使用字符组,您可以指定所需的任何分隔符集,例如“4”、“#”和“K”:
sed -r 's/[4#K]+[^4#K]+//677g' <in >out
为一个合理的 awk
方法请参考steeldriver 的回答但是这里还有另一个循环遍历列并仅FS
当它们的数量<= 676时才打印它们(用分隔):
awk '{for (i=1;i<=676;i++) {printf (i==1?"":FS)$i}; print ""}' <in >out
对于字符组,您必须指定输出的输出字段分隔符,例如[4#K]
和"sep"
:
awk -F'[4#K]' '{for (i=1;i<=676;i++) {printf (i==1?"":"sep")$i}; print ""}' <in >out
答案2
对于单字符分隔符(例如空格或逗号),我建议使用命令cut
而不是awk
或sed
。
不过既然你awk
具体问到了,我思考一个合理的方法是减少字段数量:
awk -v last=676 '{NF = last} 1' datafile
在 GNU Awk ( gawk
) 中测试过,并且mawk
。
答案3
你可以使用
mlr --nidx --fs ' ' --repifs cat inputFile.csv | cut -d ' ' -f-2
以这种方式磨坊主/mlr
您管理字段分隔符(如果您有多个空格,则每个字段一个空格),并且使用 cut 您提取(在我的例子中)前两个字段。
从
1807 1452 1598 1 6.655713 A B A B
1808 1452 1763 1 9.362033 0 0 A B
1809 1452 1527 2 6.728534 A B A A
1810 1452 1367 2 9.4055 A B A A B
到
1807 1452
1808 1452
1809 1452
1810 1452
关于 Miller 期权的一些注释:
--nidx
是设置格式;这是一个通用的索引编号表(第一个字段是 1,第二个字段是 2,等等);--fs
设置分隔符(这里是一个空格);--repifs
表示字段分隔符连续多次出现算作一个cat
将输入记录直接传递到输出。