我正在尝试遍历文件中的每一行,并查找并提取以${
开头并以}
结尾的字母。因此,作为最终输出,我只期望SOLDIR
和TEMP
(来自inputfile.sh
)。
我尝试使用以下脚本,但似乎匹配并仅提取模式TEMP
的第二次出现。我也尝试在最后添加g
,但它没有帮助。请问有谁可以让我知道如何在同一行上匹配和提取两个/多个事件?
inputfile.sh:
.
.
SOLPORT=\`grep -A 4 '\[LocalDB\]' \${SOLDIR}/solidhac.ini | grep \${TEMP} | awk '{print $2}'\`
.
.
script.sh:
infile='inputfile.sh'
while read line ; do
echo $line | sed 's%.*${\([^}]*\)}.*%\1%g'
done < "$infile"
答案 0 :(得分:9)
我可以提出grep
解决方案吗?
grep -oP '(?<=\${).*?(?=})'
它使用Perl风格的lookaround assertions并且懒惰地匹配'${'
和'}'
之间的任何内容。
给你的线路,我得到
$ echo "SOLPORT=\`grep -A 4 '[LocalDB]' \${SOLDIR}/solidhac.ini | grep \${TEMP} | awk '{print $2}'\`" | grep -oP '(?<=\${).*?(?=})'
SOLDIR
TEMP
答案 1 :(得分:2)
这可能对您有用(但可能仅适用于您的特定输入行):
sed 's/[^$]*\(${[^}]\+}\)[^$]*/\1\t/g;s/$[^{$]\+//g'
答案 2 :(得分:1)
使用sed从一行中提取多个匹配并不像我想象的那么糟糕,但它仍然相当深奥且难以阅读:
l
一切都在一条线上:
$ echo 'Hello ${var1}, how is your ${var2}' | sed -En '
# Replace ${PREFIX}${TARGET}${SUFFIX} with ${PREFIX}\a${TARGET}\n${SUFFIX}
s#\$\{([^}]+)\}#\a\1\n#
# Continue to next line if no matches.
/\n/!b
# Remove the prefix.
s#.*\a##
# Print up to the first newline.
P
# Delete up to the first newline and reprocess what's left of the line.
D
'
var1
var2
由于POSIX扩展正则表达式不支持非贪婪量词或在括号表达式中放置换行符,因此我使用sed -En 's#\$\{([^}]+)\}#\a\1\n#;/\n/!b;s#.*\a##;P;D'
字符(BEL
)作为结尾处的哨兵前缀而不是换行符。可以使用换行符,但第二次替换必须是有问题的\a
,这可能涉及正则表达式引擎的病态回溯量。