为 grep 创建正则表达式模式

为 grep 创建正则表达式模式

所以我有一个像这样的字符串LST = fr, de, pl, ru, ch, us, uk, ca。在这里,我必须为将来的 grep 操作创建一个正则表达式模式,因此我必须修改我的字符串以像这样匹配fr\|de\|pl\|ru\|ch\|us\|uk\|ca

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

不幸的是,tr , "\\|"不会替换给定的字符来创建我的正则表达式模式...结果是frdeplruchusukca。如何创建正则表达式模式,或者如何(例如)找到 LST 变量的出现de并将找到的值设置为我的 LST 变量?

配置.ini 示例

; sample of ini file
[SITE_PREF]

LST = fr, de, pl, ru, ch, us, uk, ca
TASKLIST = T1,TT3,TT0

答案1

好的,首先,tr一次只能处理一个字符,它不能,用 a 替换 a \|(一到两个字符)。因此,请使用sedsed -e 's/,/\\|/'

第二,你可以将 thegrepseds 结合起来,这似乎适用于 Bash 和 GNU sed:

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

(这基本上是说:在所有匹配的行上/^LST *=/,执行大括号中的操作:两个s替换并p打印该行。)

三,对于您的tr,您应该将逗号更改为反斜杠或管道,具体取决于引用是否有效,即

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

但你没有,反而一无所获。我无法用 Bash 重现这一点,但该set语法看起来像csh,并且我使用 时得到了一些奇怪的行为tcsh。在某些情况下。不是全部。

好的:

$ 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

不太好:

$ 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

我能看到的唯一区别是第二种情况下的星号。

答案2

awk

... | awk -F'= ' '{gsub(", ", "\\|", $2); print $2}'
  • -F '= '将字段分隔符设置为=

  • gsub(", ", "\\|", $2)将第二个字段中的,全部替换为\|

  • print $2打印第二个字段

例子:

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

答案3

fr\|de\|pl\|ru\|ch\|us\|uk\|ca然而,作为 grep 的正则表达式,它不是标准/可移植的:

fr
de
pl
ru
ch
us
uk
ca

这是用换行符分隔的项目,是标准的,也可以用于grep -F固定字符串搜索(因此,如果您的搜索项包含正则表达式运算符,则不会出现问题)。

所以你可以这样做(这里使用 POSIX shell 语法,你不想用于csh脚本编写):

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

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

如果您的grep实现支持它,您还可以传递-w仅搜索整个单词的选项。

答案4

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

相关内容