npross
npross

Reputation: 1888

Specific search and replace with sed

I have the following data in a file:

@ARTICLE{Abazajian03,
   year = 2003,
   volume = 203,
   volume = 203,
@ARTICLE{Alexander03,
   year = 2003,
@ARTICLE{Anderson03,
   year = 2003,
@INPROCEEDINGS{Antonucci03,
   year = 2003,
@ARTICLE{Baes03,
   year = 2003,
   year = 2003,
....

and want to transform the "names and dates" from e.g. Abazajian03 to Abazajian2003, and Alexander03 to Alexander2003 etc.

This line almost does it, I think sed can do this

sed 's/[a-z][A-Z]*03/2003/' infile.txt > outfile.txt

But takes off the last alpha-charterer in the replacement(!!) e.g. @ARTICLE{Abazajia2003,

Thanks!!

Upvotes: 1

Views: 57

Answers (3)

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

Awk solution:

awk '/^@/{ sub(/03/,"2003") }1' infile.txt

The output (for your current input):

@ARTICLE{Abazajian2003,
   year = 2017,
   volume = 203,
   volume = 203,
@ARTICLE{Alexander2003,
   year = 2017,
@ARTICLE{Anderson2003,
   year = 2017,
@INPROCEEDINGS{Antonucci2003,
   year = 2017,
@ARTICLE{Baes2003,
   year = 2017,
   year = 2017,

Upvotes: 1

Rahul Verma
Rahul Verma

Reputation: 3079

Using sed

sed -r 's/(^@.*)([0-1][0-9],)/\120\2/g; s/(^@.*)([7-9][0-9],)/\119\2/g;'

To understand how it works : We are capturing two groups for each line starting with @
For eg. For first line in your input: One group before 03, and second 03, itself. Then we are replacing it with first_group20second_group

[0-1][0-9], to match years from 00 to 17 to which 20 will be prepended
[7-9][0-9], to match years from 70 to 99 to which 19 will be prepended

Output:

@ARTICLE{Abazajian2003,
   year = 2003,
   volume = 203,
   volume = 203,
@ARTICLE{Alexander2003,
   year = 2003,
@ARTICLE{Anderson2003,
   year = 2003,
@INPROCEEDINGS{Antonucci2003,
   year = 2003,
@ARTICLE{Baes2003,
   year = 2003,
   year = 2003,

Upvotes: 0

CWLiu
CWLiu

Reputation: 4043

sed '/^@/ {s/\([0-6][0-9]\)/20\1/;s/\([7-9][0-9]\)/19\1/}' infile.txt > outfile.txt

Brief explanation,

  • /^@/: Process lines matching the regex '^@'
  • s/\([0-6][0-9]\)/20\1/: substitute '[0-6][0-9]' prefix with '20' and \1 refers to the corresponding matching embraced by parentheses
  • s/\([7-9][0-9]\)/19\1/: substitute '[7-9][0-9]' to prefix with '19' and \1 refers to the corresponding matching embraced by parentheses

Upvotes: 0

Related Questions