Grepping все строки на одной строке из нескольких файлов - PullRequest
0 голосов
/ 11 марта 2019

Попытка найти способ grep всех имен в одной строке для 100 файлов.grepping все имена, доступные в каждом файле, должны отображаться в одной строке.

FILE1

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

FILE2

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

Вывод, который я на самом деле хочу, (включить файлимя в качестве префикса.)

FILE1:COMPANY1,COMPANY2,COMPANY3    
FILE2:COMPANY99

Я пытался grep -oP '(?<="company":")[^"]*' *, но я получаю такие результаты:

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

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

Есть два инструмента, которые могут взять вывод вашей команды grep и переформатировать его так, как вы хотите. Первый инструмент - GNU datamash . Во-вторых, tsv-суммировать из пакета eBay tsv-utils (отказ от ответственности: я автор). Оба инструмента решают эту проблему одинаково:

$ # 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
0 голосов
/ 11 марта 2019

Не могли бы вы попробовать следующее.

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 само решение, поскольку мы НЕ используем несколько команд или вложенных оболочек).

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}}'
...