Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 拆分一个大的txt文件以执行grep-unix_Bash_Unix_Split_Grep - Fatal编程技术网

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

Bash 拆分一个大的txt文件以执行grep-unix,bash,unix,split,grep,Bash,Unix,Split,Grep,我使用txt文件(unix、shell脚本),这些文件由管道分隔成数百万个字段,而不是由\n或\r分隔。 大概是这样的: field1a|field2a|field3a|field4a|field5a|field6a|[...]|field1d|field2d|field3d|field4d|field5d|field6d|[...]|field1m|field2m|field3m|field4m|field5m|field6m|[...]|field1z|field2z|field3z|fie

我使用txt文件(unix、shell脚本),这些文件由管道分隔成数百万个字段,而不是由
\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=姓名;field2=姓氏;field3=手机;field4=电子邮件;field5=办公电话;field6=skype

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


我认为一个好的解决方案是编写一个脚本,用“\n”分隔每6个字段,然后执行grep。我是对的?多谢各位

用六块一块打印行怎么样

$ 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

$awk'BEGIN{FS=OFS=“|”}{for(i=1;i如果要将文件视为多行,请将
\n
设为字段分隔符。例如,要获取第二列,只需执行以下操作:

tr \| \\n < input-file | sed -n 2p
tr\|\\n
要查看哪些列与正则表达式匹配,请执行以下操作:

tr \| \\n < input-file | grep -n regex 
tr\|\\n
您可以使用
sed
将行拆分为多行:

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

  • 我们必须使用
    (){}
    的大反斜杠转义,这使得代码稍微不可读

  • 但简而言之:

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

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

      • |
        后跟一个“|”

      • 上述内容显然是一列,并与随附的论文

      • 整个组重复6次
        {6}

      • 这一部分又与随附的论文
        组合在一起,形成一整套

本学期的其余部分很容易阅读:

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

  • \1
    指sed表达式中的“第一”组(启动的“第一”组,因此它是由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|
这就是正则表达式的工作原理:

  • [^ |]
    是任何非
    字符
  • [^ |]\+
    是至少一个非
    字符的序列
  • [^ |]\+
    是至少一个非
    字符后跟
    的序列
  • \([^ |]\+\124;\)
    是至少一个非
    字符的序列,后跟一个
    ,组合在一起
  • \([^ |]\+\\}{6\}
    是6个连续的此类组
  • \(\([^ |]\+\\{6\}\)
    是6个连续的此类组,分组在一起
替换只需按6组的顺序进行,并在末尾添加一个换行符。

使用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|
$cat a
田1A |田2A |田3A |田5A |田6A |田1D |田2D |田3D |田4D |田5D |田6D |田1M |田2M |田3M |田4M |田5M |田6M |田1Z 1246ZӞ|

$awk-F“|”{for(i=1;i下面是如何使用
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
调整为适合您的字段数。

只是想知道,为什么您的文本文件是这样构建的?为什么有人会否决这个问题?因为OP必须以愚蠢的格式处理一个文件?我收到了这个文件。就像一个文件归档器,保存所有处理过的信息:D
sed
通常是这是一个独立的二进制文件,因此不依赖于您正在使用的shell。@umläute:您是对的,但是转义括号和
可能有不同的要求,所以我认为最好提及这一点。是的,第二个是我所需要的!谢谢。+1尽管修改
ORS
awk-v RS=“|”更好{ORS=(NR%7?”|“:“\n”)}1'文件
谢谢。将
“|”更改为
RS
嗯,很好!我知道这个问题可以用NR/RS技巧:)