1

I want to change some characters in a string I create. I make a filelisting and from each file I need to append the "stat" information. For example filename "K181_111126.CATProduct" results in "K181_111126.CATProduct.2011-11-28 13:33:33.722342000 +0100". The last 16 characters I don´t need, I solved it with:

find . -type f -exec stat -c%n.%y {} \; | sed 's/.\{16\}$//'

Result: "K181_111126.CATProduct.2011-11-28 13:33:33" My problem is, that I need to change the space (9th character from behind) between date and time with a "-" and all ":" in the time (13:33:33) with a dot "."
The strings all have different length, so that I can only count from behind.

2
  • 1
    please format your question for clarity.. see unix.stackexchange.com/editing-help Commented Jul 13, 2017 at 14:15
  • If you have a GNU-based system, you might find it easier to start from find's built-in -printf date-time options e.g. find . -type f -printf '%f.%Tx-%TH.%TM.%TS\n' | sed 's/\.[^.]*$//' Commented Jul 13, 2017 at 14:36

3 Answers 3

2

Replace the space and the colons at the same time by using a slightly longer regex.

find . -type f -exec stat -c%n.%y {} \; |
sed 's/ \(..\):\(..\):\(..\).\{16\}$/-\1.\2.\3/'

The space before the 24th character from the end is matched, then we match and capture the next 2 characters, a comma, the next 2, a comra, and another 2; then, the last 16 are matched and replaced with nothing. The first captured expression can be recalled using a backreference \1 (the second with \2, etc). In other words, the two digits after the space are "replaced" with themselves, i.e. effectively retained, followed by a dot, the next two, etc.

1

I think this is what you are looking for:

$ s='K181_111126.CATProduct.2011-11-28 13:33:33.722342000 +0100'
$ echo "$s" | rev | sed -E 's/.{16}//; s/:/./; s/:/./; s/ /-/' | rev
K181_111126.CATProduct.2011-11-28-13.33.33

This uses rev to reverse input line character wise so that it is easier to process and finally rev again

  • s/.{16}// delete first 16 characters
  • s/:/./; s/:/./ change first two : to .
  • s/ /-/ change first space to -
0
find ... |
sed -Ee '
  s/.{16}$//
  :a;s/:([^:[:blank:]]*)$/.\1/;ta
  s/[[:blank:]]([^[:blank:]]+)$/-\1/
'

Where after the deleting the trailing 16 chars just as you did, we setup a loop to progressively convert the : -> . and when done, change the last most blank char to a dash. This is necessary as the filename may also comprise blank chars and we need to ignore those.

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.