![使用 Bash 从文本文件中提取标记的字符串](https://linux22.com/image/23136/%E4%BD%BF%E7%94%A8%20Bash%20%E4%BB%8E%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E4%B8%AD%E6%8F%90%E5%8F%96%E6%A0%87%E8%AE%B0%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
我有以下样式的文件 - 这些是参数化配置文件;#
根据环境,字符中的值将替换为数据库中的实际值。
ABC=#PARAMETER_1#:#PARAMETER_2#
SOMETHING_ELSE=#PARAMETER_1#
SOMETHING_NEW=#PARAMETER_2##PARAMETER_3#
我想从这些文件中提取哈希/井号 ( #
) 字符之间的值,以便我可以轻松识别所需的参数。没有标准的列宽或类似的东西,唯一的标准是两个#
字符之间的任何内容都被数据库中的值替换。
这是理想的已清理、重复数据删除的输出:
PARAMETER_1
PARAMETER_2
PARAMETER_3
我见过这问题,但关键的区别在于,在我的情况下,特定行上可以有任意数量的变量。
我已经用 Bash 标记了这个问题,但不一定是这样,它可以是 perl 等,它只需要从 Unix 中的命令行运行即可。
答案1
作为第一个想法,awk
:
awk -vRS='#[^#]+#' 'RT{gsub(/#/,"",RT);p[RT]=1}END{for(i in p)print i}' the_file
但此决定可能取决于您必须执行的其他操作。
说明按照评论中的要求。
awk -vRS='#[^#]+#' ' # use /#[^#]+#/ as record separator
RT { # record terminator not empty?
gsub(/#/,"",RT) # remove the # parameter delimiter markup
p[RT]=1 # store it as key in array p
}
END { # end of input?
for (i in p) print i # loop through array p and print each key
}' the_file
重要的部分是使用RT
(记录终止符)内置变量:
RT The record terminator. Gawk sets RT to the input text that matched the character or regular expression specified by RS.