【发布时间】:2010-08-20 15:49:02
【问题描述】:
如何从包含这些行的文件中提取具有非常特定模式的字符串之间的文本?例如:
input:a_log.gz:make=BMW&year=2000&owner=Peter
我想从本质上捕获make=BMW&year=2000 的部分。我知道这一行可以以“input:(任意数量的字符).gz:”开头并以“owner=Peter”结尾
【问题讨论】:
如何从包含这些行的文件中提取具有非常特定模式的字符串之间的文本?例如:
input:a_log.gz:make=BMW&year=2000&owner=Peter
我想从本质上捕获make=BMW&year=2000 的部分。我知道这一行可以以“input:(任意数量的字符).gz:”开头并以“owner=Peter”结尾
【问题讨论】:
使用正则表达式:input:.*?\.gz:(.*?)&?owner=Peter。捕获将包含第二个冒号和“owner=Peter”之间的内容,修剪 & 符号。
【讨论】:
sed 's/input:.*?\.gz:(.*?)&?owner=Peter/\1/' <myfile
sed。
试试这个:
sed -n 's/.*:\([^&]*&[^&]*\)&.*/\1/p' file
这将提取第二个冒号和第二个&符号之间的所有内容,无论之前和之后是什么(如果有更多的冒号或&符号,它可能无法正常工作)。
【讨论】:
你可以使用 shell(bash/ksh)
$ s="input:a_log.gz:make=BMW&year=2000&owner=Peter"
$ s=${s##*gz:}
$ echo ${s%%owner=Peter*}
make=BMW&year=2000&
如果你想要 sed
$ echo ${s} | sed 's/input.*gz://;s/owner=Peter//'
make=BMW&year=2000&
【讨论】:
>echo "input:a_log.gz:make=BMW&year=2000&owner=Peter"|sed -e "s/input:.*.gz://g" -e "s/&owner.*//g"
make=BMW&year=2000
【讨论】:
我没有看到使用 awk 的答案:
awk '{ match($0, /input:.*\.gz:/);
m = RSTART+RLENGTH;
n = index($0, "&owner=Peter") - m;
print substr($0,m,n)
}'
该方法是sh 版本(参数扩展的子字符串)和sed(正则表达式)版本之间的混合。这是因为awk RE 缺少反向引用。
【讨论】:
awk,如我的“AWK 编程语言”副本中所述。 gawk != awk(虽然可能是 gawk > awk)。对我来说,使用awk 的优势之一是默认可用性,当您编写gawk 特定代码时它会消失。