繁体   English   中英

拆分一个大的txt文件以执行grep-UNIX

[英]Split a big txt file to do grep - unix

我使用txt文件(unix,shell脚本),这些txt文件通过管道用数百万个字段分隔,而不用\\n\\r分隔。 像这样的东西:

field1a|field2a|field3a|field4a|field5a|field6a|[...]|field1d|field2d|field3d|field4d|field5d|field6d|[...]|field1m|field2m|field3m|field4m|field5m|field6m|[...]|field1z|field2z|field3z|field4z|field5z|field6z|

所有文本都在同一行中。

每个文件的字段数是固定的。

(在此示例中,我有field1=name; field2=surname; field3=mobile phone; field4=email; field5=office phone; field6=skype

当我需要查找一个字段(例如field2 )时,像grep这样的命令不起作用(在同一行中)。

我认为一个好的解决方案可以是使用“ \\ n”分割每6个字段的脚本,然后再执行grep。 我是正确的? 非常感谢你!

用awk:

$ cat a
field1a|field2a|field3a|field4a|field5a|field6a|field1d|field2d|field3d|field4d|field5d|field6d|field1m|field2m|field3m|field4m|field5m|field6m|field1z|field2z|field3z|field4z|field5z|field6z|



$ awk -F"|" '{for (i=1;i<NF;i=i+6) {for (j=0; j<6; j++) printf $(i+j)"|"; printf "\n"}}' a

field1a|field2a|field3a|field4a|field5a|field6a|
field1d|field2d|field3d|field4d|field5d|field6d|
field1m|field2m|field3m|field4m|field5m|field6m|
field1z|field2z|field3z|field4z|field5z|field6z|

在这里,您可以轻松设置行的长度。

希望这可以帮助 !

您可以使用sed将行拆分为多行:

 sed 's/\(\([^|]*|\)\{6\}\)/\1\n/g' input.txt > output.txt

说明:

  • 我们必须对(){}使用大量的反斜杠转义,这会使代码有些难以理解。

  • 简而言之:

    • s//\\1之间s/ (([^|]*|){6})术语(([^|]*|){6})为了可读性删除了反斜杠)将匹配:

      • [^|]*除'|'以外的任何字符,重复多次

      • | 后跟一个“ |”

      • 上面的内容显然是一栏,并与括起来的括号()组合在一起

      • 整个组重复6次{6}

      • 然后再将其与括起来的括号()组合在一起,形成一个完整的集合

该术语的其余部分很容易理解:

  • 将上述(6个字段的整个数据集)替换为\\1\\n//g之间的部分)

  • \\1表示sed-expression中的“第一个”组(已启动的“第一个”组,因此是6个字段的整个数据集)

  • \\n是换行符

  • 因此,请自行替换6个字段的整个数据集,然后再换行

  • 并重复这样做(结尾的g

您可以使用sed每6转换一次| 换行。

在我的tcsh版本中,我可以执行以下操作:

sed 's/\(\([^|]\+|\)\{6\}\)/\1\n/g' filename

考虑一下:

> cat bla
a1|b2|c3|d4|

> sed 's/\(\([^|]\+|\)\{6\}\)/\1\n/g' bla
a1|b2|
c3|d4|

正则表达式的工作方式如下:

  • [^|]是非| 字符。
  • [^|]\\+是至少一个非|的序列。 字符。
  • [^|]\\+| 是至少一种非序列| 字符后跟|
  • \\([^|]\\+|\\)是至少一个非|的序列。 字符后跟| ,分组在一起
  • \\([^|]\\+|\\)\\{6\\}是6个连续的此类组。
  • \\(\\([^|]\\+|\\)\\{6\\}\\)是6个连续的这样的组,被分组在一起。

替换仅需按6个组的顺序进行,并在末尾添加换行符。

这是我将如何使用awk做到这一点

awk -v RS="|" '{printf $0 (NR%7?RS:"\n")}' file
field1a|field2a|field3a|field4a|field5a|field6a|[...]
field1d|field2d|field3d|field4d|field5d|field6d|[...]
field1m|field2m|field3m|field4m|field5m|field6m|[...]
field1z|field2z|field3z|field4z|field5z|field6z|

只需将NR%7调整为适合您的字段数即可。

怎样将行打印在六个块上?

$ awk 'BEGIN{FS=OFS="|"} {for (i=1; i<=NF; i+=6) {print $(i), $(i+1), $(i+2), $(i+3), $(i+4), $(i+5)}}' file
field1a|field2a|field3a|field4a|field5a|field6a
field1d|field2d|field3d|field4d|field5d|field6d
field1m|field2m|field3m|field4m|field5m|field6m
field1z|field2z|field3z|field4z|field5z|field6z

说明

  • BEGIN{FS=OFS="|"}设置输入和输出字段分隔符为|
  • {for (i=1; i<=NF; i+=6) {print $(i), $(i+1), $(i+2), $(i+3), $(i+4), $(i+5)}}循环浏览6个块上的项目。每次打印六个。 print最终写出新行时,就完成了。

如果要将文件视为多行,请使用\\n字段分隔符。 例如,要获取第二列,只需执行以下操作:

tr \| \\n < input-file | sed -n 2p

要查看哪些列与正则表达式匹配,请执行以下操作:

tr \| \\n < input-file | grep -n regex 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM