0

I have header files that have a lot of #define statements like: #define GPSVersion 0x000;

I would like to write a Bash script to extract the text GPSVersion into a file. But how do I use grep to do that? I can find the pattern #define but how do I find the text following #define ? Thanks.

2
  • Did you ask for the particular GPSVersion define or for all the defines in the file? Commented Feb 19, 2012 at 17:50
  • @DavidCosta I should have made it clearer, I meant all defines in the file. I want to find the text that follows #define. The GPSVersion text is one example. Commented Feb 19, 2012 at 18:05

5 Answers 5

1
echo "#define GPSVersion 0x000;" | awk '{print $2}'

cat file.h | grep ^'#define' | awk '{print $2}'
Sign up to request clarification or add additional context in comments.

4 Comments

I have many lines like this, so the generic version is to use `awk `{print $2}`1 ?
This may print extraneous lines that contain #define in comments. Use '^#define to print only lines that start with #define. Using cat starts an extra unnecessary process. grep $PATTERN < $FILE is more efficient. Since you're always printing the second field, awk is overkill; cut is far more efficient.
@AdamLiss You are probably right. I gave the up check before I ran the code in the answer above. (My wife called me to breakfast).
I've edited the code and added some @AdamLiss recommendations.
0

Try this one-liner that uses Perl instead of grep:

 perl -ne 'print "$1\n" if $_ =~ /#define \b(\w+?)\b.*/' < header.h

where header.h is the file that has #define GPSVersion 0x000 in it.

Comments

0

Steps:

  1. catyour file. (an echo in sample)
  2. filter lines including ones that starts by #define
  3. get second field

Command:

echo "#define GPSVersion 0x000;" | grep ^"#defin" | cut -d" " -f2

2 Comments

This will print the second field, which is GPSVersion
It is -- thanks for the correction! I misread the question, thinking all of the headers defined various values for GPSVersion and that the OP wanted to collect the actual version numbers. I've updated my answer accordingly.
0

I think this works for you:

grep -r '#define[[:space:]]*GPSVERSION[[:space:]].*' . | tr -s ' \t' '\t' | cut -f 3

grep -r : scans ALL the files in the specified directory and subdirectories '#define[[:space:]]*GPSVERSION[[:space:]].*' : is a regexp that matches all the #define directives, ignoring the whitespacing and considering only #defines that have a value assigned to them.

Grep prints its output, then the output is passed to tr -s ' \t' '\t' which convert blanks to something suitable for cut

Finally cut -f3 prints only the desired value of the define.

It works well except: comment defines (//#define) and filenames with spaces in them.

Comments

0
$find /path/to/root/of/source/tree -name '*.h' |
  xargs grep '^#define.*GPSVersion' | cut -d' ' -f 2

Explanation:

The find command will print all files in the source tree whose names end in .h -- that is, all of your header files.

The xargs command passes the file names to grep, which will print all the lines that begin with #define, followed by one or more characters, followed by GPSVersion.

The cut command will print the 2nd field (the text that's being #defined), using the space characters as delimiters between fields.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.