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). Commented 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.