在最近的一次更新中,neomutt改变了它处理regexp匹配的方式,这打破了我配置中不多的URI。解决方案似乎是用%20
替换URI中的空格。这不是什么大问题,除非我在多个配置文件中定义了很多虚拟邮箱。下面是一个配置的示例:
"Inbox" "notmuch://?query=folder:gmail/INBOX and tag:inbox" \
"Drafts" "notmuch://?query=folder:gmail/Drafts" \
"Sent Mail" "notmuch://?query=folder:gmail/Sent%20Mail" \
"Trash" "notmuch://?query=folder:gmail/Trash" \
"Today" "notmuch://?query=to:rsstinnett@gmail.com and date:today" \
"Yesterday" "notmuch://?query=to:rsstinnett@gmail.com and date:yesterday" \
"This Week" "notmuch://?query=to:rsstinnett@gmail.com and date:this_week" \
"Todo" "notmuch://?query=to:rsstinnett@gmail.com and tag:todo" \
"Starred" "notmuch://?query=to:rsstinnett@gmail.com and tag:star" \
"Burning Man" 'notmuch://?query=folder:"gmail/Burning Man"' \
" Work List" 'notmuch://?query=folder:"gmail/Burning Man/Work List"' \
"ATXHS" 'notmuch://?query=folder:"gmail/ATX Hackerspace" and not tag:archive' \
" ATXHS Members" 'notmuch://?query=folder:"gmail/ATX Hackerspace/Members" and not tag:archive' \
" ATXHS Discuss" 'notmuch://?query=folder:"gmail/ATX Hackerspace/Discuss" and not tag:archive' \
" ATXHS Announce" 'notmuch://?query=folder:"gmail/ATX Hackerspace/Announce" and not tag:archive'
使用sed
、awk
、grep
等,如何在不影响" and not tag:archive"
的情况下将"gmail/ATX Hackerspace"
更改为"gmail/ATX%20Hackerspace"
?
我知道还需要做其他的修改,但这是我唯一的一个被卡住的地方。基本上,我需要修改folder:"
和下一个双引号之间的空格。我不知道这是否合理。
3条答案
按热度按时间y0u0uwnf1#
基于 I need to change the spacesbetween
folder:"
and the next instance of a double quote,下面的代码看起来是一个非常简单且可读性很强的解决方案:它基本上是一个while循环
s/(folder:"[^ "]*) /\1%20/
试图挑选在结束"
之前跟随folder:"
的第一空格(如果有的话),ta
实际上t
测试任何s
命令是否在当前行上成功,并且如果是这种情况,则它将控制转移到标记为:a
的行。更新
关于
-E
选项,我仅在GNU sed上测试了上面的答案。Ed Morton在OSX/BSD上测试了它,我提供的命令给出了不变的输出。我认为原因可能是
-E
,或者可能是ta
之后缺少了;
,但根据Ed Morton的尝试,情况似乎并非如此。根据以下摘自GNU sed手册页的内容,我最初认为该命令符合POSIX:
此外,在this GNU page上,我看到
过去这是一个GNU扩展,但-E扩展后来被添加到POSIX标准(http://austingroupbugs.net/view.php?id=528)中,因此使用-E是为了可移植性。
然而,到目前为止,这就是GNU对POSIX的评价。
如果你去那个链接,问题历史部分的最后一行是日期 2020-03-18 15:37,并写着 Resolved =〉Applied,但我不知道这些网站与POSIX有什么关系。
底线是:我不知道
-E
是否与POSIX兼容。u59ebvdq2#
在每个UNIX系统上的任何shell中使用任何awk:
jdzmm42g3#
为了好玩,这里有另一个只使用
sed
的解决方案。(在生产环境中,当有更好的工具可用时,没有充分的理由单独使用sed
;但这仍然是一个很好的训练练习。)与Enrico De Angelis发布的简单而简短的解决方案相比,他的方法和我下面提出的方法有两个不同之处。
首先,如果“替换”文本中包含空格(例如,如果每个空格都必须替换为百分号后带有空格的
% 20
),恩里科的答案中的方法就不起作用。但在更一般的问题中,Enrico解决方案中的循环方法可能导致无限循环。第二,循环方法要求对每个必须替换的空格运行一次regexp匹配。相反,虽然下面的解决方案也运行
s
命令多次,但它是每个输入行的固定运行次数,而不管要替换的空格数。同样,在OP的问题中,这不是问题,因为每一行上只有很少的空格需要替换。下面的方法在更一般的情况下可能是有帮助的,其中每一行需要大量的替换。这个想法相对简单,但是
sed
只有两个缓冲区,我们可以在这两个缓冲区之间来回切换,我们可以“保存”一部分不需要修改的字符串,然后在剩下的字符串中进行修改。由于我们只有两个缓冲区和三个相关的子字符串,我们被迫在解决方案的前半部分进行“太多的修改,”然后在后半部分撤销不必要的修改。这个解决方案也有一个明显的弱点:如果字符串的最后一部分已经包含了%20
(在与folder
相关的结束双引号之后),则这些字符串将被更改为空格,即使它们在原始字符串中不是空格。我想知道是否有更好的方法沿着这些路线(意思是,具体地说,不涉及循环过程)。
通常,前导的
$
和>
是shell提示符(不是sed
命令的一部分)。EDIT正如EdMorton在下面的评论中指出的,懒惰量词是Perl的一个特性,在
sed
中不受支持。以下是POSIX ERE兼容版本: