我有一个数据文件,它可以有N行,每行由M个由空格分隔的元素组成。目前,我想将每一行分成几个段。换句话说,假设段数为3;那么原始文件将被分成3个文件,每个文件有N行,每行有M/3个元素。除了编写 C++ 或 Java 程序之外,是否有任何有效的方法可以在 Unix/Linux 上完成此任务?
答案1
这可满足同一文件中不同数量的字段的需求,并且最后一个段仅部分填充,即字段少于指定的字段(每个段)。
但请注意,如果行中的字段数导致段数少于指定的段数,则不会针对这些不足的段向输出文件写入任何内容。
awk -v 'ncol=5' -v 'pfix=file' '{
fldn = 0
sfix = 1
segs = NF/ncol
# round up if number of field is not evenly divisible by number of columns
segs = (segs == int(segs)) ?segs :int(segs)+1
while (fldn != NF) {
fmod = (++fldn) % ncol
printf "%s%s", dlim, $(fldn) >> pfix sfix
if (fmod == 1 ) { dlim = " " }
if ((fmod==0 ) || (fldn==NF)) {
printf "\n" >> pfix sfix
dlim = ""; sfix++
}
}
}' infile
答案2
如果您的文件是干净的,我建议使用标准应用程序cut
cut
有你至少应该知道的三个标志
- -d 定义分隔符(TAB 是默认值
- -f 选择字段
- -c 选择字符范围
您可以选择使用组合 -d -f 或 -c 如果您的文件不是制表符分隔的,而是由空格很好地分隔的,您可以这样做
cut -d' ' -f1-3
选择前三列。
如果你想选择第 4 列,即字符 25 和 36 之间,你可以这样做
cut -c25-36
答案3
这是你想要的?
awk '{ print $1 $2 $3 > file1; print $4 $5 $6 > file2; print $7 $8 $9 > file3 }' originalfile
或者你想要一些更通用的东西?
awk -v 'n=3' -v 'prefix=pref' '{
for (i = 0; i < n; i++) {
for (j = 0; j < NF / n; j++) {
printf("%s ", $(i + j + 1)) > prefix i
}
printf("\n") > prefix i
}
}' originalfile
注意:这依赖于所有行具有相同列数的假设。
答案4
sep_file.ksh
#!/bin/ksh
FILENAME=$1
SEG=$2
SEG_NO=1
while [[ $SEG_NO -le $SEG ]]
do
awk '{CL=NF/'"$SEG"';CL=(CL==int(CL)?CL:int(CL)+1);LS=(('"$SEG_NO"'-1)*CL)+1;LE=LS+CL-1;if(LE>NF)LE=NF;for(i=LS;i<=LE;i++)printf("%s ",$i);printf("\n")}' $FILENAME > ${FILENAME}_$SEG_NO
SEG_NO=`echo "$SEG_NO + 1"|bc`
done
用法:./sep_file.ksh <file_name_to_read> <no_of_segments>