1

I have a file which contains hardware information. For example

Part Number                          : 0-0000-00
Board Revision                       : 0
PCB Serial Number                    : ZKZHY5431ZG
PCB Fab Part Number                  : 0-0000-00
Deviation Number                     : 0
MAC Address                          : FC:58:9A:07:4F:D4
MAC Address Block Size               : 4
PCA Assembly Number                  : 000-00000-00
PCA Revision Number                  : 0
Product/Model Number                 : IG21-EU-E-K9
Top Assembly Part Number             : 074-123960-01
Top Revision Number                  : 02
Top Assembly Serial Number           : PSZ24351JZG
RMA Test History                     : 00
RMA History                          : 00
PEP Product Identifier (PID)         : IG21-EU-E-K9
PEP Version Identifier (VID)         : V00
System Flags                         : 00
Controller Type                      : 0000
Host Controller Type                 : 0000   
Mfr Service Date                     : 2020.12.28-47:59:59

I want to exclude few lines while doing cat on hardware file. To achieve this I tried below command

cat hardware.txt | grep -Ev 'Part Number|Board Revision|PCB Fab Part Number|PCA Assembly Number|PCA Revision Number'

it works fine but there is one small problem. When I run this command it also exclude Top Assembly Part Number. It is because Part Number is hitting another line as well.

I even tried -w option with grep but with that I didn't get any output on console. It looks like exact match will fail as we have some value for each field in the hardware file

can someone please help me . how can I avoid exclusion of Top Assembly Part Number

5
  • 3
    Try anchoring the pattern at the beginning of the line. Read up on ^ and $ in man grep.
    – dirkt
    Sep 16, 2021 at 7:37
  • @dirkt I think that merits to be an answer
    – AdminBee
    Sep 16, 2021 at 7:51
  • @dirkt Thank you for quick answer. My problem is resolved with the below change cat hardware.txt | grep -Ev '^Part Number|Board Revision|PCB Fab Part Number|PCA Assembly Number|PCA Revision Number'
    – vivek
    Sep 16, 2021 at 8:01
  • 2
    @dirkt please don't post answers as comments. That circumvents the quality control mechanisms of the site since comments cannot be downvoted or edited and also can discourage other users from posting answers, meaning the question can remain unanswered.
    – terdon
    Sep 16, 2021 at 8:13
  • @vivek now think about the difference between ^Part Number|Board Revision... and ^(Part Number|Board Revision...), and why the variant in the answer is better.
    – dirkt
    Sep 16, 2021 at 10:26

2 Answers 2

4

You just need to anchor your patterns to the start of the line using ^. You also don't need cat, all you need is grep:

$ grep -Ev '^(Part Number|Board Revision|PCB Fab Part Number|PCA Assembly Number|PCA Revision Number)' file
PCB Serial Number                    : ZKZHY5431ZG
Deviation Number                     : 0
MAC Address                          : FC:58:9A:07:4F:D4
MAC Address Block Size               : 4
Product/Model Number                 : IG21-EU-E-K9
Top Assembly Part Number             : 074-123960-01
Top Revision Number                  : 02
Top Assembly Serial Number           : PSZ24351JZG
RMA Test History                     : 00
RMA History                          : 00
PEP Product Identifier (PID)         : IG21-EU-E-K9
PEP Version Identifier (VID)         : V00
System Flags                         : 00
Controller Type                      : 0000
Host Controller Type                 : 0000   
Mfr Service Date                     : 2020.12.28-47:59:59

To be even safer, you can make sure to only match if the pattern is followed by 0 or more spaces and then a ::

grep -Ev '^(Part Number|Board Revision|PCB Fab Part Number|PCA Assembly Number|PCA Revision Number) *:' file
2
  • Actually I'd pre-process those lines with sed -e 's/ *:/:/' and then anchor the regex between ^` and :. It will also produce more beautiful output (for programs, maybe not for humans).
    – U. Windl
    May 31, 2022 at 23:44
  • @U.Windl that is a completely different output. You would break the alignment, making the text uglier and harder to read.
    – terdon
    Jun 1, 2022 at 8:20
-1

While grep is fine for these kind of tasks, I just wanted to point out another way of doing it in bash for example:

#!/usr/bin/env bash

lines_to_ignore=("Part Number" "Board Revision" "PCB Fab Part Number" "PCA Assembly" "PCA Revision Number")
lines=()
while read -r line 
   do
    for e in "${lines_to_ignore[@]}"
      do
        [[ $line == *$e* ]] || [[ -z $line ]] && continue 2
      done
    lines+=("$line")
done < hardware.txt
printf '%s\n' "${lines[@]}"

or in awk

awk 'NF && !/^(Part Number|Board Revision|PCB Fab Part Number|PCA Assembly|PCA Revision Number)/' hardware.txt
5
  • Regarding the bash script, please read why-is-using-a-shell-loop-to-process-text-considered-bad-practice. Also, never name a variable l as it looks far too much like the number 1 and so obfuscates your code.
    – Ed Morton
    Sep 17, 2021 at 15:42
  • Thanks for the pointers. About it being slow, sure I do agree on that. About not using l as a var name? That's a weak argument. Btw a number '1` can't even be used as a var. Also I quite know how bash works and its drawbacks are. There is no silver bullet. Sep 17, 2021 at 17:12
  • 1
    You don't think [[ $line == *$l* ]] || [[ -z $line ]] && continue 2 might be confused with [[ $line == *$1* ]] || [[ -z $line ]] && continue 2? From that example alone you can see that 1 can be/is used in the same context as a variable in shell scripts.
    – Ed Morton
    Sep 17, 2021 at 18:16
  • I'm not suggesting there's any silver bullets, but there are some things that are best avoided and a shell while-read loop just to process text is one of them for the reasons stated in the reference I provided since there are better alternatives.
    – Ed Morton
    Sep 17, 2021 at 18:19
  • 1
    Alright Ed you convinced me. I will update the answer. In retrospect, I think better var names can be used. Thanks again! Sep 17, 2021 at 18:35

You must log in to answer this question.

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