0

I'm trying to figure out how to use sed (I realise I could use other tools but I'd like to know how to do it in sed, if it really makes more sense in another tool please advise) to edit a file containing lines like this:

1234561234567809912345612345678 00000999988STRING ONE EX30 0600000001 K XXYY 1122331122334409922334466554433 00000123499STRING TWO EX99 0600000002 K XXYY 

as well as a number of other lines which are of different formats.

the strings STRING ONE and STRING TWO are in positions 47-64 (including their following spaces).

I want to change text in positions 65-80 to another value dependant on the contents of positions 47-64.

So for the STRING ONE line, chars 65-80 would be amended to "AAAABBBBCCCC " (4 trailing spaces).

In the STRING TWO line, chars 65-80 would be amended to "XXXYYYZZZ " (4 trailing spaces).

I've got this far:

sed 's/^\(.\{64\}\)EX/\1234567890 /'

which will substitute "EX" at char 65 to "234567890 " but this

  • doesn't account for picking the correct lines (with STRING ONE or STRING TWO)
  • only substitutes "EX"

& there are other things I'm not following here.

  • Why the dot between the open bracket & the backslash curly bracket?
  • why precede the 1 with a backslash (which seems to be necessary but causes the 1 not to be in the substitute string)?

I expect I could get this done using grep & manipulating output to temporary files or environment variables but would be nice to know if I can do it more elegantly.

1 Answer 1

0

. in a pattern means "any character". .\{64\} means "64 characters", any of them.

\1 is a back reference to the first matching group, i.e. what was matched by the first pair of \(...\) parentheses. To insert a literal 1, don't prepend the backslash.

You can use "addresses" in sed to restrict a command only to some lines, e.g.

sed '/^.\{46\}STRING ONE \{8\}/s/^\(.\{64\}\).\{16\}/\1AAAABBBBCCCC /' 

which reads If the line starts with 46 characters followed by STRING ONE and 8 spaces, remember the first 64 characters in \1, and replace them and the following 16 characters by the remembered characters followed by AAAABBBBCCCC and four spaces.

To add more commands with addresses, separate them with semicolons or use multiple -e switches:

sed -e '/address1/s/pattern1/replacement1/;/address2/s/pattern2/replacement2/' sed -e '/address1/s/pattern1/replacement1/' -e '/address2/s/pattern2/replacement2/' 
1
  • great thanks choroba. Solved my problem & explained it clearly. Commented Dec 2, 2016 at 16:47

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.