0

I have multiple files containing several different lines. Among the lines, I am interested only in the ones starting with a specific pattern, such as:

USER1    Info> :FERRARI:RED,:LAMBORGHINI:ORANGE,:MASERATI:BLUE,...

In this example (with spaces as indicated).

From these lines I only need the car's make info (without the colours) so the output should look like this:

FERRARI, LAMBORGHINI and MASERATI

The car's make are always different in each file. In the example I put 3 car's make, but in each file they could be less or more. Is there an easy way to do this in bash or python? Thanks

5
  • Please have a look at stackoverflow.com/a/36211753/5217119 Hints: you need to extract columns $2,$4,$6
    – binarysta
    May 29, 2020 at 0:08
  • Thanks for the link. Actually, columns may be more than 3. I put 3 in the question only as an example, but depending on the file, they could be less or more, and I can't know how many of them are in each file before.
    – ginopino
    May 29, 2020 at 0:14
  • Edited. My apologize for not being clear enough. I hope now it is clearer.
    – ginopino
    May 29, 2020 at 0:23
  • Note that AA, and BB, are also "words which is between the two colons". What specific criteria distinguish the parts you want to retain from these? May 29, 2020 at 0:26
  • the comma is the separator. I will try to edit the question with a more specific example
    – ginopino
    May 29, 2020 at 0:57

2 Answers 2

0

To extract every word (not contains comma) which is between the two colons

grep -oHnE ":[^,]*:" files* | awk 'BEGIN{FS=":"} {x=$1$2; a[x]=a[x]","$4} END{for(x in a) print a[x]}' | sed 's/^,//'

Assuming we have file car_info.txt

cat car_info.txt
USER1    Info> :FERRARI:RED,:LAMBORGHINI:ORANGE,:MASERATI:BLUE
USER1    Info> :FERRARI:RED,:LAMBORGHINI:ORANGE
USER1    Info> :FERRARI:RED,:LAMBORGHINI:ORANGE,:MASERATI:BLUE


grep -oHnE ":[^,]*:" car_info.txt 
car_info.txt:1::FERRARI:
car_info.txt:1::LAMBORGHINI:
car_info.txt:1::MASERATI:
car_info.txt:2::FERRARI:
car_info.txt:2::LAMBORGHINI:
car_info.txt:3::FERRARI:
car_info.txt:3::LAMBORGHINI:
car_info.txt:3::MASERATI:

grep

  • -o prints only the matched parts of a matching line
  • -H prints filenames
  • -n prints line numbers
  • -E to support extended-regex

Now the strategy is to make the lines with same filename:line to be shown in one line

awk 'BEGIN{FS=":"} {x=$1$2;a[x]=a[x]","$4} END{for(x in a) print a[x]}'
  • BEGIN{FS=":"} setting the field separator to :
  • x=$1$2 put filename and line in x
  • create a key-value a with key=x and adding the 4th field to it's value in each line with same x
  • for(x in a) print a[x] print the values of the key-value a

sed 's/^,//' is for removing , from the begining of lines

8
  • Thanks for your answer. I tried this, but it won't recognize the first part of the line: *** Unbound variable: USER (You're accessing an undefined variable or function `USER')
    – ginopino
    May 29, 2020 at 1:19
  • Thank you again for your help. Actually, I tried it now but the only thing I got are the commas. I copied your script as it is and changed "files*" with the file name. I am really new to this things, so I apologize if I am doing some very basic error.
    – ginopino
    May 29, 2020 at 18:06
  • the file I am using to try your script is car_info.txt
    – ginopino
    May 29, 2020 at 18:30
  • well.. this quite did the job. The output is a list of the words in the file between the two colons. Now the only thing I need to do is to select only the lines starting with "USER1 Info> "
    – ginopino
    May 29, 2020 at 18:40
  • @ginopino I found the problem, please have a look at the answer
    – binarysta
    May 29, 2020 at 18:52
0

awk -F':' /^USER1.\*Info/' {print $2" "$4" "$6}' < infile

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .