How to remove the first colon ':' from a timestamp?

I am new to programming!!

Can anyone help to remove the : at the first position in a timestamp: :29.06.2019 23:03:17

Presently I am trying to do it using awk/cut commands as shown below:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2)"
echo "$TDS"


29.06.2019 23

And the output is not what I wanted! I want to print it as 29.06.2019 23:03:17.


To cut off the first character, you can also use cut -c:

$ echo ":29.06.2019 23:03:17" | cut -c 2-
29.06.2019 23:03:17

Use

cut -d: -f2-

instead of

cut -d: -f2

to get anything from the second field to the end of line:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2-)"
echo "$TDS"

awk is a cool tool, and you can solve very complex tasks with it. But for your question I would rather stick to the basic capabilities of bash.

For this easy substing removal, I would do the following:

zehe="Logfile started :29.06.2019 23:03:17"
echo "${zehe#*:}"

this will print:

29.06.2019 23:03:17

When I was in your position and started to learn programming and bash, I learned a lot of this Handbook:

ABS - Advanced Bash-Scripting Guide

Some more examples and interesting information to your problem can be found here, look for 'Substring Removal'.


Here is a sed solution:

$ echo ':29.06.2019 23:03:17' | sed 's/^://'
29.06.2019 23:03:17

What the command sed 's/^://' is doing is substitute s the colon character : from the beginning ^ of each line with the empty string //.

Here is a tricky awk solution, where we changing the field separator to ^:, described above, and output the second field (of each line):

$ echo ':29.06.2019 23:03:17' | awk -F'^:' '{print $2}'
29.06.2019 23:03:17

The task could be accomplished also with grep (explanation), probably this could be the fastest solution for large amount of data:

$ echo 'Logfile started :29.06.2019 23:03:17' | grep -Po '^Logfile started :\K.*'
29.06.2019 23:03:17

Or process the file directly by the following command, where the limitation ^ is removed:

grep -Po 'Logfile started :\K.*' process.log

The above could be achieved also by sed and capture groups ()->\1:

sed -nr 's/^.*Logfile started :(.*)$/\1/p' process.log

Where the expression ^.*<something>.*$ will match the whole line, that contains <something>. The command s/old/new/ will substitute this line by the content of the first capture group (the expression in the brackets could be more concrete). The option -r enables the extended regular expressions. The option -n will suppress the normal output of sed and finally the command p will print the matches.


Since you're already processing this in awk, you may as well do the whole thing directly:

$ echo "foo bar :29.06.2019 23:03:17" |  awk '{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

The sub command's general format is sub(/REGEX/, REPLACEMENT, TARGET) and will replace all matches for the regular expression REGEX with the string REPLACEMENT in the input string TARGET. Here, we are replacing the first : (^ means "the beginning") from the 3rd field ($3) with nothing.

Of course, if you're doing that in awk, you may as well do everything in awk and get the whole thing done in a single operation:

$ echo "Logfile started :29.06.2019 23:03:17" | 
    awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

Or, in your case:

TDS="$(awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' process.log)"
echo "$TDS"