Sed: Difference between revisions
Jump to navigation
Jump to search
Line 70: | Line 70: | ||
s/\n/ /g |
s/\n/ /g |
||
b a |
b a |
||
</source> |
|||
=== Recursive patterns === |
|||
For instance, to transform a path like <tt>/usr/local/share/bin/../../../bin/foo<tt> into <tt>/usr/bin/foo</tt>: |
|||
<source lang=text> |
|||
s!^([^./])!\./\1! # Prefix with './' unless starts with '.' or '/' |
|||
s!/./!/!g # Remove any './' in middle |
|||
:a s!/[^/]*[^/.]/\.\.!!g # Remove /foo/.. (1st letter must not be '/', last letter must not be '.') |
|||
t a # ... and repeat until no more substitutions |
|||
</source> |
|||
<source lang=bash> |
|||
echo "/usr/local/share/bin/../../../bin/foo" | sed -r 's!^([^./])!\./\1!; s!/a./!/!g; :a s!/[^/]*[^/.]/\.\.!!g; t a' |
|||
</source> |
|||
Test paths: |
|||
<source lang=bash> |
|||
/usr/local/share/../../../bin/foo # /bin/foo |
|||
/usr/local/./share/../../../bin/foo # /bin/foo |
|||
./usr/../bin/foo # ./bin/foo |
|||
usr/../bin/foo # ./bin/foo |
|||
usr/../bin # ./bin |
|||
usr/../bin/.. # . |
|||
usr/../bin/../.. # ./.. |
|||
</source> |
</source> |
Revision as of 14:24, 16 July 2012
References
- The SED Homepage on SourceForge
- The SED FAQ
- The SED man page
- Sed, a stream editor
- The sed one-liners
Installation
It is recommended to add the following alias in your ~/.bashrc:
alias sed="sed -r"
Of course, this alias has no effect on shell script. There you'll have to specify the option explicitly at each invokation.
Usage
Some basic usage:
sed [OPTION]... {script-only-if-no-other-script} [input-file]...
sed -n # Silent - suppress automatic printing of pattern space
sed -r # Use extended regular expression
sed -i "s/foo/bar/" *.txt # In-place file modification
Use of address commands a\text, i\text, c\text. The command is terminated by a *newline*. To insert a newline character, use \n:
$ cat mytext
First line
Second line
$ cat mysedscript
1 {i\inserted text
s/$/ (not anymore)/g}
$ sed -f mysedscript mytext
inserted text
First line (not anymore)
Second line
# All on one line: use echo -e to generate the newline that terminates the command i\
$ echo -e "1 {i\\inserted text\ns/$/ (not anymore)/g}"| sed -f - mytext
inserted text
First line (not anymore)
Second line
#Same result without command \i:
$ sed "1 {s/^/inserted text\n/; s/$/ (not anymore)/}" mytext
Regular expressions
See Regular Expressions.
Script Examples
Remove <script>...</script> HTML tag
s!<script[>\x20\t].*</script>!!g
/<script[>\x20\t]/{
s!<script[>\x20\t].*!!g
:NEXTCYCLE
n
/<\/script>/!{
s!.*!!g
b NEXTCYCLE
}
s!.*</script>!!g
}
Remove newlines
Newline characters are added to the pattern space when using the append command N. The script below removes all newlines from standard input:
:a N
s/\n/ /g
b a
Recursive patterns
For instance, to transform a path like /usr/local/share/bin/../../../bin/foo into /usr/bin/foo:
s!^([^./])!\./\1! # Prefix with './' unless starts with '.' or '/'
s!/./!/!g # Remove any './' in middle
:a s!/[^/]*[^/.]/\.\.!!g # Remove /foo/.. (1st letter must not be '/', last letter must not be '.')
t a # ... and repeat until no more substitutions
echo "/usr/local/share/bin/../../../bin/foo" | sed -r 's!^([^./])!\./\1!; s!/a./!/!g; :a s!/[^/]*[^/.]/\.\.!!g; t a'
Test paths:
/usr/local/share/../../../bin/foo # /bin/foo
/usr/local/./share/../../../bin/foo # /bin/foo
./usr/../bin/foo # ./bin/foo
usr/../bin/foo # ./bin/foo
usr/../bin # ./bin
usr/../bin/.. # .
usr/../bin/../.. # ./..