How to substitute spaces with %20 in a substring of a line across multiple files using sed, awk, grep etc

downtime

In a recent update neomutt changed how it handles regexp matching and it's breaking my notmuch URI's in my config. The solution seems to be replacing the spaces in the URI with %20. This wouldn't be a huge deal except that I have a lot of virtual mailboxes defined across multiple config files. So here is a sample of one config:

"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:[email protected] and date:today" \
"Yesterday"             "notmuch://?query=to:[email protected] and date:yesterday" \
"This Week"             "notmuch://?query=to:[email protected] and date:this_week" \
"Todo"                  "notmuch://?query=to:[email protected] and tag:todo" \
"Starred"               "notmuch://?query=to:[email protected] 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'

Using sed, awk, grep, or whatever, how do I change "gmail/ATX Hackerspace" to "gmail/ATX%20Hackerspace" without effecting " and not tag:archive"?

I know that other changes need to be made, but this is the only one that I'm stuck on. Basically, I need to change the spaces between folder:" and the next instance of a double quote. I don't know if this can even be done reasonably.

Enlico

Based on I need to change the spaces between folder:" and the next instance of a double quote, the following seems to be a very easy and fairly readable solution:

sed -E ':a;s/(folder:"[^ "]*) /\1%20/;ta' yourinput

It is basically a while loop where

  • the body s/(folder:"[^ "]*) /\1%20/ tries to pick the first, if any, space that follows folder:" before the closing ",
  • the condition to repeat the loop is that the attempt was successful (i.e. the substitution was done indeed); ta indeed tests if any s command was successful on the current line and, if this is the case, it transfer the control to the line labelled :a.

Update

Concerning the -E option, I have tested the answer above only on GNU sed. Ed Morton has tested it on OSX/BSD and the command I provided gives an unchanged output.

I thought the reason could be -E, or maybe a missing ; after ta, but this does not seem to be the case, based on Ed Morton's attempts.

I initially thought the command was POSIX-compliant, based on a the following excerpt from GNU sed's man page:

-E, -r, --regexp-extended

              use extended regular expressions in the script (for portability
              use POSIX -E).

Furhtermore on this GNU page, I read

Historically this was a GNU extension, but the -E extension has since been added to the POSIX standard (http://austingroupbugs.net/view.php?id=528), so use -E for portability.

Up to this point, however, this is what GNU says of POSIX.

If you go to that link, the last line in the Issue history section is dated 2020-03-18 15:37 and reads Resolved => Applied, but I don't know how that sites relates to POSIX.

The bottom line is: I don't know if -E is POSIX-compliant.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How can I filter a multi-line pattern across a text file with bash, only using grep, awk and/or sed?

How do I use grep, awk, or sed to get a substring of a line up until a string literal?

how to extract line portion on the basis of start substring and end substring using sed or awk

awk grep or sed : how to match two files

How to comment out multiple line matching a regex using sed or awk

chunking screen output using grep/head/awk/sed/etc

How to perform a multiline grep across multiple files?

How to substitute substring with dynamic number of spaces

Using grep or sed to substitute words not matching a pattern

Extract domain then paste into the same line using sed/awk/grep/perl

awk (or sed/grep) to get occurrences of substring

How pass files on I have used grep to sed with -n switch to substitute files

how to extract parts of file into separate files in linux using awk or grep or sed commands

Find files and pattern matching, NOT AND, using grep or awk or sed

Find files matching one pattern, but not another, using grep, awk or sed

Combine text files by title using grep awk sed

How to strip multiple spaces to one using sed?

How to instruct sed to substitute only once while using multiple substitute expressions?

How well does grep/sed/awk perform on very large files?

Grep a line then print awk until a certain substring

How to print empty spaces in first column using awk or sed

How to substitute multiple words with spaces in R?

Extract substring in Linux environemnt using Sed/awk/grep or any other tool

How to uncomment the a specific line which contains specific text in a hocon file using bash script(sed,awk..etc)

extract multiple items on single line using grep/sed/perl

Can I grep/awk/sed a line for multiple matches in a single line and get the info after it?

How to substitute part of substring using regex in VBScript?

How to use sed/awk/grep

How can I substitute just the last occurrence of -) in a string using sed, bash or awk?