4

I have a file in the following format:

ABCD 01206001022T01YA022T01YA022T07SO 09:20:38
ABCD 01206001022ACION 09:24:40
ABCD 04006001021S01UK 09:24:42
ABCD 7878696621321312 23213213213213
ABCD ASADSADSFSSDSSD 09:24:50

Basically except the first field, all other fields are different.

Requirement: I want timestamp on each line. If a timestamp is missing on any line, I want to append the timestamp of the previous line to the end of missing line (Example 4th line above). How can I achieve this?

  • When you say "timestamp" you mean just the time of day? Nothing more elaborate such as the date? – slm Jul 6 '13 at 23:27
4

This awk should do it:

awk '{ 
         if ( $NF ~ /[0-9]+:[0-9]+:[0-9]+/ ) {
            lasttime = $NF
            print
         } else {
            print $0, lasttime
         }
     }' < myfile.txt
2

Here's a bash solution in case that matters. It does make use of a single awk, but that could probably be refactored out if needed:

while read line ; do
  ncol=$(echo "$line" | awk '{print $NF}')
  if [[ "$ncol" == *:*:* ]]; then
    tmstmp="$ncol"
    echo "$line"
    continue
  fi
  echo "$line $tmstmp"

done < 82031.txt

The file 82031.txt includes the following:

ABCD 01206001022T01YA022T01YA022T07SO 09:20:38
ABCD 01206001022ACION 09:24:40
ABCD 04006001021S01UK 09:24:42
ABCD 7878696621321312 23213213213213
ABCD ASADSADSFSSDSSD 09:24:50

Running the above script produces the following:

ABCD 01206001022T01YA022T01YA022T07SO 09:20:38
ABCD 01206001022ACION 09:24:40
ABCD 04006001021S01UK 09:24:42
ABCD 7878696621321312 23213213213213 09:24:42
ABCD ASADSADSFSSDSSD 09:24:50

pure Bash solution

Here's an alternative that uses nothing but Bash. Instead of using awk to pull out the last column from a line of input from the .txt file, we're using Bash's read command on the while loop. The options -ra disable backslashes from being an escape character (-r) and the -a splits the input up using the $IFS separator, putting each atoms worth of text into an element in the array ${line[@]}.

while IFS=" " read -ra line ; do
  ncol="${line[@]: -1:1}"
  if [[ "$ncol" == *:*:* ]]; then
    tmstmp="$ncol"
    echo "${line[@]}"
    continue
  fi
  echo "${line[@]} $tmstmp"

done < 82031.txt

This bit, ${line[@]: -1:1} pulls out the last column of the array ${line[@]}.

  • Using read -a to read into an array rather than string would be the way to eliminate the call to awk. – jordanm Jul 7 '13 at 3:04
  • @jordanm - thanks I've added an example using your tip. – slm Jul 7 '13 at 7:34
0

One more bash solution

[[ ! -f $1 ]] && { echo -e "\tUsage:\t\n\t\t$0\t<input_file>\n"; exit 1; }

while read -ra line;
do
        if [[ ${line[@]} =~ [0-9]+:[0-9]+:[0-9]+ ]]; then
                echo ${line[@]}
                lasttime=${line[@]: -1:1}
        else

                echo ${line[@]} $lasttime
        fi
done < $1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.