我整天都在努力寻找解决方案。我最终在这里访问了一个提供两个命令的问题。他们是:
dict_by_time = {'t_1': {'id_1': 'some_state_object_1',
'id_2': 'some_state_object_2'},
't_2': {'id_1': 'some_state_object_3',
'id_2': 'some_state_object_4'}
dict_by_id = {'id_1': {'t_1': 'some_state_object_1',
't_2': 'some_state_object_3'},
'id_2': {'t_1': 'some_state_object_2',
't_2': 'some_state_object_4'}
第一个应该给出在字符串中找到的所有百分比,而第二个应该仅在期望一个百分比的情况下使用。我的字符串会有多个,因此我一直在尝试使用第一个。但是,它将返回字符串中的所有数字,并且echo blabla 20% a13724bla-bla244 35% | sed -e 's/[^%0-9 ]*//g;s/ */\n/g' | sed -n '/%/p'
echo blabla 20% a13724bla-bla244 35% | sed 's/.*[ \t][ \t]*\([0-9][0-9]*\)%.*/\1/'
代表空格。
当我尝试使用第二条命令时,我得到了列表中不需要的最后一个百分比。我需要第一个百分比。任何帮助,将不胜感激。
答案 0 :(得分:3)
perl
将更易于使用,因为它支持非贪婪量词
$ echo 'blabla 20% a13724bla-bla244 35%' | perl -pe 's/.*?(\d+%).*/$1/'
20%
.*?
至少与任何字符匹配(\d+%)
第一个数字,后跟%
组合.*
该行的其余部分$1
将行替换为()
内的文本答案 1 :(得分:2)
问题在于定义的正则表达式,.*
总是会通过尝试匹配可用的最长字符串而变得贪婪。因此,第二次尝试直接尝试匹配最后一次出现的序列。
您可以在下面调整正则表达式。使用反向匹配组来匹配所有非数字后跟%
的字符,重复该操作,直到第一个模式是一个数字后跟{{1}的字符}并打印出来
%
在这种情况下,记住使用sed 's/^[^0-9%]*\([0-9]*\)%.*/\1/'
或awk
会容易得多。 POSIX格式的perl
正则表达式匹配函数可以按以下方式执行此操作。 awk
函数扫描与正则表达式匹配的最左边的子字符串
match()
答案 2 :(得分:2)
如果有grep
个职位,那可能是最简单的工作:
$ echo blabla 20% a13724bla-bla244 35% |
grep -o "[0-9]\+ \?%" # at least one number, possibly a space and %
20%
35%
,如果只需要第一个,则将前一个管道输送到head -1
:
$ echo blabla 20% a13724bla-bla244 35% |
grep -o "[0-9]\+ \?%" | # at least one number, possibly a space and %
head -1 # take the first
20%
答案 3 :(得分:1)
将空格转换为新行和grep,以%结尾的行:
$ echo 'blabla 20% a13724bla-bla244 35%' | tr ' ' '\n' | grep '%$'
20%
35%
如果您有嵌入式空间,请显示一个示例,说明如何区分嵌入式和非嵌入式,以寻求更全面的(咳嗽)解决方案。
如果您担心误报,请坚持使用与格式兼容的前导数字:有符号,整数,小数,科学等。Chomp空白等。
通过拆分,您可以绕过所有贪婪的恶作剧,并且可以从事匹配业务。