5 added 761 characters in body
source | link

Your script reads the whole file into a variable and then iterates over the value of that variable. This has three issues:

  1. In the most general case, one may not know the size of the input file, which means that under some circumstances, the variable may become very big.
  2. Looping over the unquoted value of the variable will rely on the shell splitting the data on whitespaces (spaces, tabs and newlines). If the data contains any whitespaces apart from newlines, the loop will probably do the wrong thing.
  3. The shell will perform filename globbing on the values of the unquoted variable before looping over it. This means that if the data contains globbing patterns, such as * or [...], then these will be matched against existing filenames.

This answer uses the fact that the timestamps used are sane in the sense that they later timestamps sort after earlier ones (at least in the POSIX locale).

This answer uses the fact that the timestamps used are sane in the sense that they later timestamps sort after earlier ones (at least in the POSIX locale).

Your script reads the whole file into a variable and then iterates over the value of that variable. This has three issues:

  1. In the most general case, one may not know the size of the input file, which means that under some circumstances, the variable may become very big.
  2. Looping over the unquoted value of the variable will rely on the shell splitting the data on whitespaces (spaces, tabs and newlines). If the data contains any whitespaces apart from newlines, the loop will probably do the wrong thing.
  3. The shell will perform filename globbing on the values of the unquoted variable before looping over it. This means that if the data contains globbing patterns, such as * or [...], then these will be matched against existing filenames.

This answer uses the fact that the timestamps used are sane in the sense that they later timestamps sort after earlier ones (at least in the POSIX locale).

4 added 31 characters in body
source | link

This answer uses the fact that the timestamps used are sane in the sense that they later timestamps sort after earlier ones (at least in the POSIX locale).

#!/bin/bash

while IFS= read -r line; do
    timestamp=${line%:*}            # Remove ":ERR" at the end
    timestamp=${timestamp#*:*:}     # Remove numbers from start ("0001:3002:")
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$line"
    fi
done <file

This script will take a timestamp on the same format that's in the file as its only argument. It iterates over the contents of the file file and for each line, it parses out the timestamp and compares it with the timestamp on the command line. The comparison is made using the > operator in bash and will be true if the timestamp in the file sorts (lexicographically) after the given timestamp in the current locale. If the comparison is true, the line from the file is printed.

The two separate substitutions to parse out the timestamp from the line by deleting parts of the end and beginning of the line could be replaced by

timestamp=$( cut -d ':' -f 3,4 <<<"$line" )

but this would run slower as it's calling an external utility.

Testing:

$ bash script.sh '2018/07/16:12.36.00'
Greater: 0008:3002:2018/07/16:12.36.02:ERR
Greater: 0009:3002:2018/07/16:12.36.15:ERR

If you want to output just the timestamp from the file rather than the original line, change "$line" to "$timestamp" in the printf command.

In that case, you may also speed up things by doing the looping like this:

#!/bin/bash

cut -d ':' -f 3,4 file |
while IFS= read -r timestamp; do
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$timestamp"
    fi
done

Here, we use cut to get the 3rd and 4th :-delimited columns from the file (the timestamp), which means we don't have to do any parsing of the original lines.

Related:

This answer uses the fact that the timestamps used are sane in the sense that they later timestamps sort after earlier ones.

#!/bin/bash

while IFS= read -r line; do
    timestamp=${line%:*}            # Remove ":ERR" at the end
    timestamp=${timestamp#*:*:}     # Remove numbers from start ("0001:3002:")
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$line"
    fi
done <file

This script will take a timestamp on the same format that's in the file as its only argument. It iterates over the contents of the file file and for each line, it parses out the timestamp and compares it with the timestamp on the command line. The comparison is made using the > operator in bash and will be true if the timestamp in the file sorts (lexicographically) after the given timestamp in the current locale. If the comparison is true, the line from the file is printed.

The two separate substitutions to parse out the timestamp from the line by deleting parts of the end and beginning of the line could be replaced by

timestamp=$( cut -d ':' -f 3,4 <<<"$line" )

but this would run slower as it's calling an external utility.

Testing:

$ bash script.sh '2018/07/16:12.36.00'
Greater: 0008:3002:2018/07/16:12.36.02:ERR
Greater: 0009:3002:2018/07/16:12.36.15:ERR

If you want to output just the timestamp from the file rather than the original line, change "$line" to "$timestamp" in the printf command.

In that case, you may also speed up things by doing the looping like this:

#!/bin/bash

cut -d ':' -f 3,4 file |
while IFS= read -r timestamp; do
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$timestamp"
    fi
done

Here, we use cut to get the 3rd and 4th :-delimited columns from the file (the timestamp), which means we don't have to do any parsing of the original lines.

Related:

This answer uses the fact that the timestamps used are sane in the sense that they later timestamps sort after earlier ones (at least in the POSIX locale).

#!/bin/bash

while IFS= read -r line; do
    timestamp=${line%:*}            # Remove ":ERR" at the end
    timestamp=${timestamp#*:*:}     # Remove numbers from start ("0001:3002:")
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$line"
    fi
done <file

This script will take a timestamp on the same format that's in the file as its only argument. It iterates over the contents of the file file and for each line, it parses out the timestamp and compares it with the timestamp on the command line. The comparison is made using the > operator in bash and will be true if the timestamp in the file sorts (lexicographically) after the given timestamp in the current locale. If the comparison is true, the line from the file is printed.

The two separate substitutions to parse out the timestamp from the line by deleting parts of the end and beginning of the line could be replaced by

timestamp=$( cut -d ':' -f 3,4 <<<"$line" )

but this would run slower as it's calling an external utility.

Testing:

$ bash script.sh '2018/07/16:12.36.00'
Greater: 0008:3002:2018/07/16:12.36.02:ERR
Greater: 0009:3002:2018/07/16:12.36.15:ERR

If you want to output just the timestamp from the file rather than the original line, change "$line" to "$timestamp" in the printf command.

In that case, you may also speed up things by doing the looping like this:

#!/bin/bash

cut -d ':' -f 3,4 file |
while IFS= read -r timestamp; do
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$timestamp"
    fi
done

Here, we use cut to get the 3rd and 4th :-delimited columns from the file (the timestamp), which means we don't have to do any parsing of the original lines.

Related:

3 added 128 characters in body
source | link

This answer uses the fact that the timestamps used are sane in the sense that they later timestamps sort after earlier ones.

#!/bin/bash

while IFS= read -r line; do
    timestamp=${line%:*}            # Remove ":ERR" at the end
    timestamp=${timestamp#*:*:}     # Remove numbers from start ("0001:3002:")
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$line"
    fi
done <file

This script will take a timestamp on the same format that's in the file as its only argument. It iterates over the contents of the file file and for each line, it parses out the timestamp and compares it with the timestamp on the command line. The comparison is made using the > operator in bash and will be true if the timestamp in the file sorts (lexicographically) after the given timestamp in the current locale. If the comparison is true, the line from the file is printed.

The two separate substitutions to parse out the timestamp from the line by deleting parts of the end and beginning of the line could be replaced by

timestamp=$( cut -d ':' -f 3,4 <<<"$line" )

but this would run slower as it's calling an external utility.

Testing:

$ bash script.sh '2018/07/16:12.36.00'
Greater: 0008:3002:2018/07/16:12.36.02:ERR
Greater: 0009:3002:2018/07/16:12.36.15:ERR

If you want to output just the timestamp from the file rather than the original line, change "$line" to "$timestamp" in the printf command.

In that case, you may also speed up things by doing the looping like this:

#!/bin/bash

cut -d ':' -f 3,4 file |
while IFS= read -r timestamp; do
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$timestamp"
    fi
done

Here, we use cut to get the 3rd and 4th :-delimited columns from the file (the timestamp), which means we don't have to do any parsing of the original lines.

Related:

#!/bin/bash

while IFS= read -r line; do
    timestamp=${line%:*}            # Remove ":ERR" at the end
    timestamp=${timestamp#*:*:}     # Remove numbers from start ("0001:3002:")
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$line"
    fi
done <file

This script will take a timestamp on the same format that's in the file as its only argument. It iterates over the contents of the file file and for each line, it parses out the timestamp and compares it with the timestamp on the command line. The comparison is made using the > operator in bash and will be true if the timestamp in the file sorts (lexicographically) after the given timestamp in the current locale. If the comparison is true, the line from the file is printed.

The two separate substitutions to parse out the timestamp from the line by deleting parts of the end and beginning of the line could be replaced by

timestamp=$( cut -d ':' -f 3,4 <<<"$line" )

but this would run slower as it's calling an external utility.

Testing:

$ bash script.sh '2018/07/16:12.36.00'
Greater: 0008:3002:2018/07/16:12.36.02:ERR
Greater: 0009:3002:2018/07/16:12.36.15:ERR

If you want to output just the timestamp from the file rather than the original line, change "$line" to "$timestamp" in the printf command.

In that case, you may also speed up things by doing the looping like this:

#!/bin/bash

cut -d ':' -f 3,4 file |
while IFS= read -r timestamp; do
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$timestamp"
    fi
done

Here, we use cut to get the 3rd and 4th :-delimited columns from the file (the timestamp), which means we don't have to do any parsing of the original lines.

Related:

This answer uses the fact that the timestamps used are sane in the sense that they later timestamps sort after earlier ones.

#!/bin/bash

while IFS= read -r line; do
    timestamp=${line%:*}            # Remove ":ERR" at the end
    timestamp=${timestamp#*:*:}     # Remove numbers from start ("0001:3002:")
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$line"
    fi
done <file

This script will take a timestamp on the same format that's in the file as its only argument. It iterates over the contents of the file file and for each line, it parses out the timestamp and compares it with the timestamp on the command line. The comparison is made using the > operator in bash and will be true if the timestamp in the file sorts (lexicographically) after the given timestamp in the current locale. If the comparison is true, the line from the file is printed.

The two separate substitutions to parse out the timestamp from the line by deleting parts of the end and beginning of the line could be replaced by

timestamp=$( cut -d ':' -f 3,4 <<<"$line" )

but this would run slower as it's calling an external utility.

Testing:

$ bash script.sh '2018/07/16:12.36.00'
Greater: 0008:3002:2018/07/16:12.36.02:ERR
Greater: 0009:3002:2018/07/16:12.36.15:ERR

If you want to output just the timestamp from the file rather than the original line, change "$line" to "$timestamp" in the printf command.

In that case, you may also speed up things by doing the looping like this:

#!/bin/bash

cut -d ':' -f 3,4 file |
while IFS= read -r timestamp; do
    if [[ "$timestamp" > "$1" ]]; then
        # According to the current locale, the timestamp in "$timestamp"
        # sorts after the timestamp in "$1".
        printf "Greater: %s\n" "$timestamp"
    fi
done

Here, we use cut to get the 3rd and 4th :-delimited columns from the file (the timestamp), which means we don't have to do any parsing of the original lines.

Related:

2 added 583 characters in body
source | link
1
source | link