我有一个数据文件如下所示:
>> cat file1.txt
@target G0.S0
1 6
1 4
4 2
@target G0.S0
2 4
8 9
5 7
@target G0.S0
3 5
0 9
3 7 我希望在一个新文件中使拆分列由@target G0.S0分隔,其中列设置一个,下面是前面的列,如下所示:
>> cat file2.txt
1 6 2 4 3 5
1 4 8 9 0 9
4 2 5 7 3 7 我在网上搜索,但我没有得到我想要的。
发布于 2022-11-10 02:18:42
pr,grep和tail与外壳的快速一条线.
pr "-$(grep -Fc '@target G0.S0' file1.txt)ts"' ' file1.txt | tail -n +2将输出重定向到新文件。
pr ... > file2.txt让我们把它分解一下。
pr是一种打印工具。grep -Fc '@target G0.S0' file1.txt展开为一个数字(参见:grep --help | grep -E -- ' -(F|c)' )$( )被称为命令替换。t和s是pr的选项参见:pr --help | grep -E -- '^ *-(s|t)'tail打印,请参见:tail --help | grep -- -npr -Nts' ',其中N是int/number。正如@Socowi所提到的,在编写它时存在许多限制。代码的工作假设是,@target G0.S0之间的所有行都是相等/相同数量的行,在本例中,在@target G0.S0之间有3行。(这是我的答案),如果有太多的(长数据/输入)大小,应该添加一个额外的选项,-w。正如我刚才提到的,如果文件/数据/大小/输入是大/大的,那么awk解决方案是首选的。
awk。发布于 2022-11-10 02:04:23
awk 单过程解决方案
下面的建议通过引用行号(用于循环索引1-3、存储行2-4、6-8、10-12等的递减和余数除法,每次串联)在数组中累加行。主块之前的条件不包括行1、5、9等。结束块迭代数组以打印输出,该输出被重定向到所需的新文件名。
awk ' (NR-1)%4!=0{lines[(NR-1)%4]=lines[(NR-1)%4]$0}
END{ for(line=1; line<4; line++) {print lines[line]}
} ' file1.txt > file2.txt发布于 2022-11-10 09:57:57
这可能适用于您(csplit、粘贴和sed):
csplit -qz --suppress file '/@target/' '{*}' && paste -d' ' xx* |
sed 's/ / /g' >outFile && rm xx*将输入文件拆分为连续编号的文件,其中包含要追加的每一列的一行。
粘贴中间文件,用空格分隔。
从上面的输出,删除额外的空格,输出到一个最终的文件和清理。
GNU解决方案:
sed -nE '/\n/!{:a;N;$!ba}
s/^@/\n@/;s/\S$/& /mg;tb
:b;s/^([^\n]*)((\n[^@]*)*)\n@[^\n]*\n([^\n]+)/\1\4\2\n/;tb
s/ \n/\n/;P;s/\n+$//;s/\n\n/\n@\n/g;D' file如果没有将文件读入模式空间(内存),则关闭该文件。
在模式空间的开头引入一个换行符,并在每一行的末尾提供一个空格。
迭代文件,将第一行的值追加到模式空间的第一行。替换由两个换行符处理的每个标头。
移除行尾引入的空格,并打印模式空间的第一行。
如果所有的行都已被处理过,那么模式空间的末尾将只包含新行,在这种情况下,删除它们。
否则,通过在两个换行符之间插入一个@来重新引入伪标头。
删除打印行,如果仍有要处理的行,则再次启动sed进程。
https://stackoverflow.com/questions/74381197
复制相似问题