0

So I have a string like LST = fr, de, pl, ru, ch, us, uk, ca. Here I have to create a regex pattern for the future grep operation, so for that I have to modify my string to match like this fr\|de\|pl\|ru\|ch\|us\|uk\|ca

set LST = `grep "^LST *=" /remote/file/config.ini | sed 's/LST *= *//' | sed 's/ *//g' | tr , "\|"`

Unfortunately tr , "\\|" does not replace given characters to create my regexp pattern... the result is frdeplruchusukca. How do i create a regex pattern or how can I (for example) find occurance of de and set the found value to my LST variable ?

config.ini sample

; sample of ini file
[SITE_PREF]

LST = fr, de, pl, ru, ch, us, uk, ca
TASKLIST = T1,TT3,TT0
  • So what does the input (in config.ini) look like, exactly? – ilkkachu Sep 20 '16 at 8:03
  • @ilkkachu just a simple ini file with [section] and options, initial LST string is taken from that file – PYPL Sep 20 '16 at 8:04
1

Okay, first, tr works one character at a time, it can't replace a , with a \| (one to two characters). So instead, use sed: sed -e 's/,/\\|/'

Two, you can combine the grep and the seds, this seems to work on Bash, with GNU sed:

$ LST=$(sed -n '/^LST *=/ {s/^LST *= *//; s/, */\\|/g; p}' config.ini)
$ echo "$LST"
fr\|de\|pl\|ru\|ch\|us\|uk\|ca

(That basically says: On all lines matching /^LST *=/, do the things in braces: two substitutions and print the line.)

Three, with your tr, you should get the commas changed to backslashes or pipes, depending on if the quoting works or not, i.e.

$ echo "fr,de,pl" | tr , "\|" 
fr|de|pl
$ echo "fr,de,pl" | tr , '\\|'
fr\de\pl

But you didn't, you got nothing instead. I can't reproduce that with Bash, but that set syntax looks like csh, and I get some weird behaviour with tcsh. In some cases. Not all.

Ok:

$ tcsh
> echo "fr,de,pl" | sed 's/,/\\|/'
fr\|de,pl
> set LST = `echo "fr,de,pl" | sed 's/,/\\|/'`
> printf "%s\n" "$LST"
fr\|de,pl

Not so ok:

$ tcsh 
> echo "fr,de,pl" | sed 's/, */\\|/'
fr\|de,pl
> set LST = `echo "fr,de,pl" | sed 's/, */\\|/'`
> printf "%s\n" "$LST"
fr|de,pl

The only difference I can see, is the asterisk in the second case.

  • Don't use echo for checking backslash handling. Some echo implementations, including tcsh's builtin one does do some processing of backslash sequences. – Stéphane Chazelas Sep 20 '16 at 8:43
  • @StéphaneChazelas, point, though \| isn't a C-style escape, and while it prints a newline for echo "\n", echo "\|" prints just \| without clobbering the backslash. And I get the same with printf. And /bin/echo. I can't see any sense in that behaviour, either that shell is crazy or I am. – ilkkachu Sep 20 '16 at 9:19
  • (but echo '\\' outputs one backslash, so you would miss it if you put too much backslash) That shell is a mess (less so than csh but still is), Here, I guess the * tells tcsh somehow that there's a glob involved (even if in effect, there's none) and there's an extra layer of backslash handling for glob escaping. – Stéphane Chazelas Sep 20 '16 at 9:35
1

With awk:

... | awk -F'= ' '{gsub(", ", "\\|", $2); print $2}'
  • -F '= ' sets field separator as =

  • gsub(", ", "\\|", $2) substitute all , with \| in the second field in place

  • print $2 prints the second field

Example:

$ awk -F'= ' '{gsub(", ", "\\|", $2); print $2}' <<<'LST = fr, de, pl, ru, ch, us, uk, ca'
fr\|de\|pl\|ru\|ch\|us\|uk\|ca
1

fr\|de\|pl\|ru\|ch\|us\|uk\|ca is not standard/portable as a regexp for grep, however:

fr
de
pl
ru
ch
us
uk
ca

That is with the items delimited with newline, is standard and can also be used with grep -F for fixed string search (so you don't have problems if your search terms contain regexp operators).

So you can do (here using POSIX shell syntax, you don't want to use csh for scripting):

search_term=$(
  sed '
    /^LST *= */!d
    s///
    s/ *, */\
/g' config.ini
)

grep -F -- "$search_term" some-file

If your grep implementation supports it, you can also pass the -w option to search for whole words only.

0

LST=$(grep "^LST *=" /remote/file/config.ini| sed -e 's/LST *= *//' -e 's/, */\\|/g')

0
perl -p0E '($_)= /LST = (.*)/; s/, /\\|/g' config.ini

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.