首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >以字符串分隔成新文件的分隔行,作为列Bash脚本

以字符串分隔成新文件的分隔行,作为列Bash脚本
EN

Stack Overflow用户
提问于 2022-11-09 20:45:58
回答 3查看 90关注 0票数 1

我有一个数据文件如下所示:

代码语言:javascript
复制
>> 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分隔,其中列设置一个,下面是前面的列,如下所示:

代码语言:javascript
复制
>> cat file2.txt
1 6 2 4 3 5
1 4 8 9 0 9
4 2 5 7 3 7 

我在网上搜索,但我没有得到我想要的。

EN

回答 3

Stack Overflow用户

发布于 2022-11-10 02:18:42

prgreptail与外壳的快速一条线.

代码语言:javascript
复制
pr "-$(grep -Fc '@target G0.S0' file1.txt)ts"' ' file1.txt | tail -n +2

将输出重定向到新文件。

代码语言:javascript
复制
pr ... > file2.txt

让我们把它分解一下。

  • pr是一种打印工具。
  • grep -Fc '@target G0.S0' file1.txt展开为一个数字(参见:grep --help | grep -E -- ' -(F|c)' )
  • $( )被称为命令替换
  • tspr的选项参见:pr --help | grep -E -- '^ *-(s|t)'
  • 从第二行开始的tail打印,请参见:tail --help | grep -- -n
  • 最后,命令扩展到:pr -Nts' ',其中N是int/number。

正如@Socowi所提到的,在编写它时存在许多限制。代码的工作假设是,@target G0.S0之间的所有行都是相等/相同数量的行,在本例中,在@target G0.S0之间有3行。(这是我的答案),如果有太多的(长数据/输入)大小,应该添加一个额外的选项,-w。正如我刚才提到的,如果文件/数据/大小/输入是大/大的,那么awk解决方案是首选的。

  • 对于较大的数据大小/文件,我将使用awk
票数 2
EN

Stack Overflow用户

发布于 2022-11-10 02:04:23

awk 单过程解决方案

下面的建议通过引用行号(用于循环索引1-3、存储行2-4、6-8、10-12等的递减和余数除法,每次串联)在数组中累加行。主块之前的条件不包括行1、5、9等。结束块迭代数组以打印输出,该输出被重定向到所需的新文件名。

代码语言:javascript
复制
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
票数 0
EN

Stack Overflow用户

发布于 2022-11-10 09:57:57

这可能适用于您(csplit、粘贴和sed):

代码语言:javascript
复制
csplit -qz --suppress file '/@target/' '{*}' && paste -d' ' xx* |
sed 's/  / /g' >outFile && rm xx*

将输入文件拆分为连续编号的文件,其中包含要追加的每一列的一行。

粘贴中间文件,用空格分隔。

从上面的输出,删除额外的空格,输出到一个最终的文件和清理。

GNU解决方案:

代码语言:javascript
复制
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进程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74381197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档