2

I declared a long variable containing the libraries to use during the compilation:

export LIBS="-L/usr/lib -lcurl -L/lib -lhdf5 -Wl,-rpath,/lib -L/usr/lib64 -lglpk -Wl,-rpath,/usr/local/tools/vtk-6.1.0/lib -L/usr/local/tools/vtk-6.1.0/lib -lvtkIOCore-6.1 -lvtkCommonCore-6.1 -lvtkCommonDataModel-6.1 -lvtkFiltersCore-6.1 -lvtkIOXML-6.1 -lvtkImagingCore-6.1 -lvtkIOImage-6.1 -lvtkImagingMath-6.1 -lz -L/g/g92/miguel/petsc-3.6.2/miguel-opt/lib -lpetsc -Wl,-rpath,/g/g92/miguel/petsc-3.6.2/miguel-opt/lib -lcmumps -ldmumps -lsmumps -lzmumps -lmumps_common -lpord -lscalapack -lHYPRE -L/usr/local/tools/openmpi-intel-1.8.4/lib -L/usr/local/tools/ic-14.0.174/composer_xe_2013_sp1.3.174/compiler/lib/intel64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -lml -llapack -lblas -lparmetis -lmetis -lX11 -lhwloc -lssl -lcrypto -lmpi_usempif08 -lmpi_usempi_ignore_tkr -lmpi_mpifh -lifport -lifcore -lm -lmpi -Wl,-rpath,/usr/local/tools/ic-14.0.174/lib -limf -lsvml -lirng -lipgo -ldecimal -lcilkrts -lstdc++ -lgcc_s -lirc -lpthread -lirc_s -Wl,-rpath,/usr/local/tools/openmpi-intel-1.8.4/lib -Wl,-rpath,/usr/local/tools/ic-14.0.174/composer_xe_2013_sp1.3.174/compiler/lib/intel64 -Wl,-rpath,/usr/lib/gcc/x86_64-redhat-linux/4.4.7 -ldl -Wl,-rpath,/g/g92/miguel/code/libmesh_2D/lib -L/g/g92/miguel/code/libmesh_2D/lib -lmesh_opt"

Now I would like to extract the directories that start with -L. I tried doing this:

printenv LIBS | grep -o '\b-L\w*'

but I do not obtain any result, whereas doing this (just for trying to understand what is going on)

printenv LIBS | grep -o '\b-l\w*'

extracts only the words "-linux" in my variable. I would like to obtain as a result a new variable that were like this:

/usr/lib /lib /usr/lib64-lglpk /usr/local/tools/vtk-6.1.0/lib ...

I obviously do not understand much about regular expressions and I often feel confused with the different tools used (grep, sed, awk, etc) and the answers that show an encryptic regexp with no explanation whatsoever. Could I have a useful reference please? Is the regexp syntax universal across the above mentioned different tools? Thanks.

balborian
  • 123
  • 1
    http://unix.stackexchange.com/questions/119905/why-does-my-regular-expression-work-in-x-but-not-in-y – Jeff Schaller Mar 30 '16 at 17:27
  • Check the update on my answer: actually there is a safe way to parse that string, but only as long as the spaces in the paths are escaped. – kos Mar 30 '16 at 18:16

2 Answers2

0
 echo $LIBS | awk '{for(i=1;i<=NF;i++){ if($i ~ /^-L/){print $i} } }'

grep works with lines, as sed does. awk works with fields. for such task, I'd prefer to use awk, however grep or sed could do the job as well.

Mikhail Krutov
  • 1,054
  • 2
  • 11
  • 22
0

Let's take a look at the definition of word boundary:

There are three different positions that qualify as word boundaries:

  • Before the first character in the string, if the first character is a word character.
  • After the last character in the string, if the last character is a word character.
  • Between two characters in the string, where one is a word character and the other is not a word character.

No word boundary can match in between a non-word character and a dash, because a dash is not a word character either.

Also since e.g. slashes are non-word characters as well, and since you don't have spaces in the paths, rather than matching \w* it would me more sensitive to match [^ ]*. However, since you also want to exclude part of the match, grep is not the right tool for the job, unless you're using a grep version which supports PCREs:

printenv LIBS | grep -Po '(^| )-L[^ ]*'
% printenv LIBS | grep -Po '(^| )-L\K/[^ ]*'
/usr/lib
/lib
/usr/lib64
/usr/local/tools/vtk-6.1.0/lib
/g/g92/miguel/petsc-3.6.2/miguel-opt/lib
/usr/local/tools/openmpi-intel-1.8.4/lib
/usr/local/tools/ic-14.0.174/composer_xe_2013_sp1.3.174/compiler/lib/intel64
/usr/lib/gcc/x86_64-redhat-linux/4.4.7
/g/g92/miguel/code/libmesh_2D/lib

However this relies on the paths not containing spaces, and relying on the paths not containing dashes would be just as wrong.

Generally, there's no safe way to parse that string.

My suggestion is to store the paths into an array manually.

On a second thought, I guess potential spaces in a path would be escaped in order for the path to be interpreted correctly?

If that's the case, this would be safe:

printenv LIBS | grep -Po '(^| )-L\K\/.*?(?=([^\\] |$))'
% export LIBS='-L/path\ with\ spaces -L/another\ path\ with\ spaces'
% printenv LIBS | grep -Po '(^| )-L\K\/.*?(?=([^\\] |$))'
/path\ with\ space
/another\ path\ with\ spaces
kos
  • 2,887