【问题标题】:Grepping all strings on the same line from multiple files从多个文件中提取同一行中的所有字符串
【发布时间】:2019-08-01 06:15:00
【问题描述】:

试图找到一种方法来 grep 一行上 100 个文件的所有名称。 grepping 每个文件中可用的所有名称必须出现在同一行。

文件1

"company":"COMPANY1","companyDisplayName":"CM1","company":"COMPANY2","companyDisplayName":"CM2","company":"COMPANY3","companyDisplayName":"CM3",

文件2

"company":"COMPANY99","companyDisplayName":"CM99"

我真正想要的输出是,(包括文件名作为前缀。)

FILE1:COMPANY1,COMPANY2,COMPANY3    
FILE2:COMPANY99

我尝试了grep -oP '(?<="company":")[^"]*' *,但我得到了这样的结果:

FILE1:COMPANY1
FILE1:COMPANY2
FILE1:COMPANY3
FILE2:COMPANY99

【问题讨论】:

  • 每个文件只有一行数据?

标签: awk sed command-line grep


【解决方案1】:

请您尝试关注一下。

awk -F'[,:]' '
BEGIN{
  OFS=","
}
{
  for(i=1;i<=NF;i++){
    if($i=="\"company\""){
      val=(val?val OFS:"")$(i+1)
    }
  }
  gsub(/\"/,"",val)
  print FILENAME":"val
  val=""
}
'   Input_file1  Input_file2

说明:为上述代码添加说明。

awk -F'[,:]' '                          ##Starting awk program here and setting field separator as colon OR comma here for all lines of Input_file(s).
BEGIN{                                  ##Starting BEGIN section of awk here.
  OFS=","                               ##Setting OFS as comma here.
}                                       ##Closing BEGIN BLOCK here.
{                                       ##Starting main BLOCK here.
  for(i=1;i<=NF;i++){                   ##Starting a for loop which starts from i=1 to till value of NF.
    if($i=="\"company\""){              ##Checking condition if field value is equal to "company" then do following.
      val=(val?val OFS:"")$(i+1)        ##Creating a variable named val and concatenating its own value to it each time cursor comes here.
    }                                   ##Closing BLOCK for if condition here.
  }                                     ##Closing BLOCK for, for loop here.
  gsub(/\"/,"",val)                     ##Using gsub to gklobally substitute all " in variable val here.
  print FILENAME":"val                  ##Printing filename colon and variable val here.
  val=""                                ##Nullifying variable val here.
}                                       ##Closing main BLOCK here.
'  Input_file1  Input_file2             ##Mentioning Input_file names here.

输出如下。

Input_file1:COMPANY1,COMPANY2,COMPANY3
Input_file2:COMPANY99


编辑: 添加解决方案以防 OP 需要使用 grep 并希望从其输出中获得最终输出(尽管我会建议使用 awk 解决方案本身,因为我们没有使用多个命令或子 shell)。

grep -oP '(?<="company":")[^"]*' * | awk 'BEGIN{FS=":";OFS=","} prev!=$1 && val{print prev":"val;val=""} {val=(val?val OFS:"")$2;prev=$1} END{if(val){print prev":"val}}'

【讨论】:

  • @Alpha.Mc,请您检查一下这个答案,如果这对您有帮助,请告诉我?
【解决方案2】:

有两个工具可以获取 grep 命令的输出并按照您想要的方式重新格式化它。第一个工具是GNU datamash。其次是来自 eBay 的 tsv-utils 包中的 tsv-summarize(免责声明:我是作者)。这两种工具都以类似的方式解决了这个问题:

$ # The grep output
$ echo $'FILE1:COMPANY1\nFILE1:COMPANY2\nFILE1:COMPANY3\nFILE2:COMPANY99' > grep-output.txt
$ cat grep-output.txt
FILE1:COMPANY1
FILE1:COMPANY2
FILE1:COMPANY3
FILE2:COMPANY99

$ # Using GNU datamash
$ cat grep-output.txt | datamash -field-separator : --group 1 unique 2
FILE1:COMPANY1,COMPANY2,COMPANY3
FILE2:COMPANY99

$ # Using tsv-summarize
$ cat grep-output.txt | tsv-summarize --delimiter : --group-by 1 --unique-values 2 --values-delimiter ,
FILE1:COMPANY1,COMPANY2,COMPANY3
FILE2:COMPANY99

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-10
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多