regex - How to remove leading and trailing spaces between quotes with sed? - Stack Overflow

admin2025-04-25  2

Given the following text (commands in a script):

test --my-option ' my/string my-second/string '
test --my-option ' my/string my-second/string   '
test --my-option 'my/string my-second/string  '
test --my-option '  my/string  my-second/string '
test --my-option ' my/string   '

I use the following regex: --my-option ' *([^']*?) *' with --my-option '$1' as replacement expression to get:

test --my-option 'my/string my-second/string'
test --my-option 'my/string my-second/string'
test --my-option 'my/string my-second/string'
test --my-option 'my/string  my-second/string'
test --my-option 'my/string'

Question is: how would I do this with sed?

Given the following text (commands in a script):

test --my-option ' my/string my-second/string '
test --my-option ' my/string my-second/string   '
test --my-option 'my/string my-second/string  '
test --my-option '  my/string  my-second/string '
test --my-option ' my/string   '

I use the following regex: --my-option ' *([^']*?) *' with --my-option '$1' as replacement expression to get:

test --my-option 'my/string my-second/string'
test --my-option 'my/string my-second/string'
test --my-option 'my/string my-second/string'
test --my-option 'my/string  my-second/string'
test --my-option 'my/string'

Question is: how would I do this with sed?

Share Improve this question edited Jan 16 at 13:04 Fravadona 17.3k1 gold badge28 silver badges47 bronze badges asked Jan 16 at 12:58 mikemike 4845 silver badges20 bronze badges 7
  • 1 Try sed -E "s/--my-option ' *([^[:space:]']*[^']*[^'[:space:]]) *'/--my-option '\1'/" file See the matches here regex101.com/r/SnCgbU/1 – The fourth bird Commented Jan 16 at 13:14
  • sed and perl have different regular expressions and replacement expressions. As you are apparently familiar with perl, not with sed, why not using perl? perl -pe "s/--my-option ' *([^']*?) *'/--my-option '\$1'/" (note the backslash to prevent expansion of $1 by the shell). – Renaud Pacalet Commented Jan 16 at 13:29
  • 1 @mike I see. Anyway, if you are familiar with perl-like regular expressions (as your attempt indicates), and if you don't care too much about performance, you can use perl instead of sed. You will benefit from of all its extensions, like the non-greedy matching (*?), that sed does not support and that is helpful in cases like yours. – Renaud Pacalet Commented Jan 16 at 13:43
  • 1 @Thefourthbird, works fine! – mike Commented Jan 16 at 14:24
  • 1 sed "s/' */'/; s/ *'$/'/" file? – Cyrus Commented Jan 16 at 17:28
 |  Show 2 more comments

3 Answers 3

Reset to default 2

This might work for you (GNU sed):

sed -E 's/^([^'\'']*'\'') *([^'\'' ]+( +[^'\'' ]+)*) *('\''.*)/\1\2\4/' file

Remove spaces to the right of the first ' and to the left of the next '.

Alternative:

sed -E 's/^([^'\'']*'\'') *([^'\'']*\>) */\1\2/' file

Using any sed:

$ sed "s/ *' */'/g; s/'/ '/" file
test --my-option 'my/string my-second/string'
test --my-option 'my/string my-second/string'
test --my-option 'my/string my-second/string'
test --my-option 'my/string  my-second/string'
test --my-option 'my/string'

Alternatively:

$ sed "s/' *\(.*[^ ]\)* *'/'\1'/" file
test --my-option 'my/string my-second/string'
test --my-option 'my/string my-second/string'
test --my-option 'my/string my-second/string'
test --my-option 'my/string  my-second/string'
test --my-option 'my/string'
sed -E "s/' *([^']*[^' ])? *'/'\1'/g"
  • ' * matches open singlequote and 0+ spaces
  • ([^']*[^' ])? match group 1: 0 or 1 sequence of non-quote chars ending in a non-space char. Basically requires that match group 1 end in a char other than space, and cannot have quotes.
  • *' matches 0+ spaces and close singlequote

This should handle several single-quoted strings in each line using s///g because it has exactly two singlequote chars in the match regex.

转载请注明原文地址:http://anycun.com/QandA/1745531311a90839.html