0

For example, given:

$ cat test001.txt
this
is a
 test bucket
bucket line not this one.
  bucket lein endy
    bucket and others endy
and
a ttest

How can I change the lines that start with "bucket" with "(bucket", ignoring spaces?

So far I have:

sed -i 's/^\sbucket/bucket(/g' test001.txt    

but that doesn't work (no change and no error). Then I would like to only do it for lines that also end with 'endy' (so only 2 of the 3 bucket lines).

1
  • Also end with 'endy': sed -i 's/^[[:space:]]*bucket.*endy/(bucket/g' test001.txt. . for any character and * for zero or more (greedy).
    – Ivan Chau
    Oct 24, 2013 at 3:53

3 Answers 3

4

You can use back references (e.g., \1) in your replacement-term which will replace subexpressions (things enclosed within escaped parentheses — \(…\)) in your search term. E.g.,

$ cat test001.txt | sed -e 's/^\([[:space:]]*\)\(bucket.*endy\)$/\1(\2/'
this
is a
 test bucket
bucket line not this one.
  (bucket lein endy
    (bucket and others endy
and
a ttest

will create two subexpressions:

  1. the leading spaces: ^\([[:space:]]*\)
  2. the string that starts with "bucket" and ends with "endy" (at the EOL): \(bucket.*endy\)$

It will then replace any line that matches with \1(\2, which is the whitespace, followed by an opening parenthesis, followed by the bucket..endy string.

3

Here's another approach:

sed -e '/^[[:space:]]*bucket.*endy$/s/bucket/(bucket/' file.txt

The initial /pattern/ tells sed to only work on lines containing that pattern, and the rest of it is a simple, standard substitution.

1

The \s is not part of BRE, which sed uses. In BRE \s is the same as a literal s. The equivalent of \s would be [[:space:]]. Try the following:

sed -i 's/^[[:space:]]*bucket/(bucket/g' test001.txt
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .