开发者

Struggling to combine two Greps statements

开发者 https://www.devze.com 2023-02-11 12:45 出处:网络
Greetings! I have been tasked to create a report off files we receive from our hardware suppliers. I need to grep these files for two fields \'Test_Version\' and \'Model-Manufacturer\' ; for each fie

Greetings!

I have been tasked to create a report off files we receive from our hardware suppliers. I need to grep these files for two fields 'Test_Version' and 'Model-Manufacturer' ; for each field, I need to capture their corresponding values.

When running each statement sepa开发者_如何学Pythonrately, I get the results I want:

1) for 'Test_Version', it was straightforward:

find . -name "*.VER" -exec grep 'Test_Version=' '{}' ';' -print; 

./(FILE_NAME).VER
Test_Version=2.6.3
./(FILE_NAME).VER
Test_Version=2.4.7

2) for 'Model-Manufacturer', , it was a bit tricky since what I need is across multiple lines. I solved this issue by using Perl Regex option -P.

find . -name "*.VER" -exec grep -P 'Model-Manufacturer:.\n.' '{}' ';' -print

./(FILE_NAME).VER
--> Model-Manufacturer:
D12-100
./(FILE_NAME).VER
--> Model-Manufacturer:
H21-100

Ideally, I would like to create a simple report that looks like this

(FILE_NAME)
Test_Version=2.6.3
Model-Manufacturer:    D12-100
(FILE_NAME)
Test_Version=2.4.7
Model-Manufacturer:    H21-100

My attempt to combine both greps is not working i.e nothing is found:

find . -name "*.VER" -exec grep -P 'Test_Version=.Model-Manufacturer:.\n.' '{}' ';' -print

How can I grep to search for both fields and produce the output I want?


I created a test file:

$ cat test1.VER
Test_Version=2.6.3
Model-Manufacturer:
D12-100
Test_Version=2.4.7
Model-Manufacturer:
H21-100
Test_Version=2.6.3
Model-Manufacturer:
D12-100
Test_Version=2.4.7
Model-Manufacturer:
H21-100

I created a copy, to replicate searching through multiple files:

$ cp test1.VER test2.VER

Finally, I am able to generate the report you're looking for using the following string of commands:

$ find . -name "*.VER" -print -exec egrep -A 1 'Test_Version=|Model-Manufacturer:' {} ';' | sed -e '/Model/N; s/\n/ /'
./test1.VER
Test_Version=2.6.3
Model-Manufacturer: D12-100
Test_Version=2.4.7
Model-Manufacturer: H21-100
Test_Version=2.6.3
Model-Manufacturer: D12-100
Test_Version=2.4.7
Model-Manufacturer: H21-100
./test2.VER
Test_Version=2.6.3
Model-Manufacturer: D12-100
Test_Version=2.4.7
Model-Manufacturer: H21-100
Test_Version=2.6.3
Model-Manufacturer: D12-100
Test_Version=2.4.7
Model-Manufacturer: H21-100

egrep allows for extended regular expressions, in which I'm using | as the alternation operator.

The -A flag to (e)grep, makes it provide a line of context after each match. If your input files have unwanted content after the Test_Version lines, you may need to include a grep -v command piped in between find and sed to strip out the unwanted output.


find . -name "*.VER" -exec \
    awk '/Model-Manufacturer:/ {a = $0; pnr = NR; getline; 
             if (NR != pnr) a = a FS $0; 
             flag = 1} 
         /Test_Version=/ {a = $0; flag = 1} 
         {if (flag)
             {if (FILENAME != prevf) {
                 printf "%s\n", FILENAME; 
                 prevf = FILENAME}; 
              print a;}
          flag = 0}' {} \;


I would use something like

cat {} | grep Exp1 | grep Exp1

The problem here is how to escape/embed the piping in the command. As a quick solution, you could move the two greps in a shell script and execute that from your find command. Not the most beautiful solution, though.

0

精彩评论

暂无评论...
验证码 换一张
取 消