Home > Software engineering >  shell change date within a string
shell change date within a string

Time:04-26

I found some sed examples for my dilemma. current text file is like below.

 076411-160DL        0000000052220420    000005212635883-0003-0
 138574A             0000000120220421    000012012630637-0003-1
 146054A             0000000420220422    000042012634007-0003-1
 138575A             0000000240220421    000024012630638-0003-1
 145683C             0000000145220422    000014512634671-0003-1
 137611B             0000000130220419    000013012632286-0003-0
 137618C             0000000120220420    000012012635623-0003-0

I am only changing date in the second column but I need to leave it as is and just change to the current date then out to a new file. I have the first part seperated using grep -v "\0003-0" *.txt Then I seperate the 0003-0 with grep -h "\0003-0" I then use a sed to change format and this is where it is almost there but due to numbers in front of the date it is not consistent.

sed -r "s/[2]{2}[0-8]{2}[0-9]{2}/$(date ' %y%m%d')/g"

I get it mostly how I want it but if there is a group with 8 zeros and only 1 other digit before the date I get something on the end of the new date such as 9 or 0. Any tips would be awesome. Thanks

I am only changing the date where the file ends in 0003-0 There is a space before the first column I was not aware of until now.

expected output would be

 076411-160DL        0000000052220425    000005212635883-0003-0
 138574A             0000000120220421    000012012630637-0003-1
 146054A             0000000420220422    000042012634007-0003-1
 138575A             0000000240220421    000024012630638-0003-1
 145683C             0000000145220422    000014512634671-0003-1
 137611B             0000000130220425    000013012632286-0003-0
 137618C             0000000120220425    000012012635623-0003-0

CodePudding user response:

Adding a pattern match to OP's current sed code:

$ sed -r "/-0003-0$/s/[2]{2}[0-8]{2}[0-9]{2}/$(date ' %y%m%d')/g" file
 076411-160DL        0000000052204250    000005212635883-0003-0
 138574A             0000000120220421    000012012630637-0003-1
 146054A             0000000420220422    000042012634007-0003-1
 138575A             0000000240220421    000024012630638-0003-1
 145683C             0000000145220422    000014512634671-0003-1
 137611B             0000000130220425    000013012632286-0003-0
 137618C             0000000120220425    000012012635623-0003-0

But this fails to update the first line.

One possible tweak to address the 'middle' field:

$ sed -r "/-0003-0$/s/( [0-9]{10})([0-9]{6}) /\1$(date ' %y%m%d') /" file
 076411-160DL        0000000052220425    000005212635883-0003-0
 138574A             0000000120220421    000012012630637-0003-1
 146054A             0000000420220422    000042012634007-0003-1
 138575A             0000000240220421    000024012630638-0003-1
 145683C             0000000145220422    000014512634671-0003-1
 137611B             0000000130220425    000013012632286-0003-0
 137618C             0000000120220425    000012012635623-0003-0

CodePudding user response:

Suggesting single sed command:

 sed -r '/0003-0$/s|([[:digit:]]{6}) |'$(date  %y%m%d)' |' 

CodePudding user response:

date=$(date  %y%m%d)
sed -E '/0003-0$/{s/ ([^ ]{1,10})[^ ]* / \1'"$date"' /2}'

Note that your data has a single space before the first column.

Explanation:

TLDR: Make a pattern to match fields, which also captures (up to) the first ten characters of the field for a back-reference, and substitute the second field.

  • First, filter for lines ending in 0003-0.
  • Then target the second field of each line, by using a pattern of "space, then at least one non-space character, then space".
  • The 2 at the very end means substitute the second (or N) instance of the match pattern. Hence our pattern targets the second field only.
  • The pattern captures (up to) the first ten characters of this field (using parentheses), so we can back-reference them in the replacement (using \1) and discards the remaining (six) date characters, which we replace with $date.
  • {1,10} needs to be a range of at least one character, because it must match both the first and second field, to enable us to specify the second field with 2.

Edit:

Gives:

 076411-160DL        0000000052220426    000005212635883-0003-0
 138574A             0000000120220421    000012012630637-0003-1
 146054A             0000000420220422    000042012634007-0003-1
 138575A             0000000240220421    000024012630638-0003-1
 145683C             0000000145220422    000014512634671-0003-1
 137611B             0000000130220426    000013012632286-0003-0
 137618C             0000000120220426    000012012635623-0003-0
  • Related