请求修正sed命令:修改每行指定匹配模式间的字符
Hey there! Let's sort out that sed command for you. The main issue with your current attempt is that you're using sed's line range syntax (/1,/,/,2/) when you actually need to target a character range within each line — sed treats /a/,/b/ as selecting lines from the first line containing a to the first line containing b, not the text between a and b on a single line. That's why your command wasn't working as expected.
Here's the corrected sed command that does exactly what you need:
sed -E ':a s/(1, \{[^}]*),([^}]*\}, 2)/\1 \2/; ta; s/(1, \{) /\1/' myfile.txt
Let's break down how it works:
-E: Enables extended regular expressions, making the pattern cleaner to write.:a: Defines a loop label nameda(we'll use this to repeat the replacement until all commas are gone).s/(1, \{[^}]*),([^}]*\}, 2)/\1 \2/:- Captures the part from
1, {up to a comma, then the rest of the content inside{}until}, 2. - Replaces the captured comma with a space. This targets every comma inside the curly braces between
1,and,2.
- Captures the part from
ta: If the previous replacement was successful (meaning there are still commas left), jump back to labelaand repeat the process.s/(1, \{) /\1/: Cleans up the extra space right after the opening{(since your original lines have{,which becomes{after the first replacement, this fixes it to{).
Testing it with your sample input:
Running this command on your myfile.txt will produce exactly the output you're expecting:
abc, def, 1, {jsdfsd kfgdsf lgfgd}, 2, pqr, stu
abc, def, 1, {jsdfsqwe k fdfsfl}, 2, pqr, stu
abc, def, 1, {asdasdj kgfdgdf ldsfsdf}, 2, pqr, stu
abc, def, 1, {jsds kfdsf fdsl}, 2, pqr, stu
If you prefer a more concise alternative (using Perl, which handles nested/inline ranges more intuitively), you could use:
perl -pe 's/(1, \{)(.*?)(\}, 2)/$1 . $2 =~ s|,| |gr . $3/ge' myfile.txt
This uses Perl's regex substitution with embedded code to replace all commas in the captured {} content with spaces in one go.
内容的提问来源于stack exchange,提问作者Arun Srinivasan

