Skip to main content
Code Review

Return to Answer

Fixed broken code
Source Link
200_success
  • 145.5k
  • 22
  • 190
  • 479
tail -f "$serverlog" | \
while read date time severity player message ; do
 case "$severity" in
 \[INFO\])
 case "$message" in
 *joined the game*)
 echo "$player $date $time" >> "$onlinefile"
 awksed -v player="$player" '1ドル == player { print NR }'i |-e \"$(
 while read lineno ; do
  awk -v player="$player" '1ドル == player { sedprint -iNR "${lineno"d;"}d"' "$offlinefile"
 )" done"$offlinefile"
 ;;
 *left the game*)
 echo "$player $date $time" >> "$offlinefile"
 awksed -v player="$player" '1ドル == player { print NR }'i |-e \"$(
 while read lineno ; do
  awk -v player="$player" '1ドル == player { sedprint -iNR "${lineno"d;"}d"' "$onlinefile"
 )" done"$onlinefile"
 ;;
 esac # case $message
 ;;
 esac # case $severity
done

but there could be a vulnerability if $player contained special characters such as .*. A better solution, if you have GNU awk ≥ 4.1.0 , is

awk -v player="$player" '1ドル != player' -i inplace "$offlinefile"

With other versions of awk, you could use tempfile to help you perform the edit.

tail -f "$serverlog" | \
while read date time severity player message ; do
 case "$severity" in
 \[INFO\])
 case "$message" in
 *joined the game*)
 echo "$player $date $time" >> "$onlinefile"
 awk -v player="$player" '1ドル == player { print NR }' | \
 while read lineno ; do
  sed -i "${lineno}d" "$offlinefile"
 done
 ;;
 *left the game*)
 echo "$player $date $time" >> "$offlinefile"
 awk -v player="$player" '1ドル == player { print NR }' | \
 while read lineno ; do
  sed -i "${lineno}d" "$onlinefile"
 done
 ;;
 esac # case $message
 ;;
 esac # case $severity
done

but there could be a vulnerability if $player contained special characters such as .*.

tail -f "$serverlog" | \
while read date time severity player message ; do
 case "$severity" in
 \[INFO\])
 case "$message" in
 *joined the game*)
 echo "$player $date $time" >> "$onlinefile"
 sed -i -e "$(
 awk -v player="$player" '1ドル == player { print NR "d;"}' "$offlinefile"
 )" "$offlinefile"
 ;;
 *left the game*)
 echo "$player $date $time" >> "$offlinefile"
 sed -i -e "$(
 awk -v player="$player" '1ドル == player { print NR "d;"}' "$onlinefile"
 )" "$onlinefile"
 ;;
 esac # case $message
 ;;
 esac # case $severity
done

but there could be a vulnerability if $player contained special characters such as .*. A better solution, if you have GNU awk ≥ 4.1.0 , is

awk -v player="$player" '1ドル != player' -i inplace "$offlinefile"

With other versions of awk, you could use tempfile to help you perform the edit.

Source Link
200_success
  • 145.5k
  • 22
  • 190
  • 479

Your goal is to monitor $serverlog continuously, and update $onlinefile and $offlinefile accordingly. The fact that you repeatedly close and reopen $serverlog is problematic, not only for performance reasons, but as you remarked, you risk processing the same line endlessly. Therefore, your general strategy should be to keep the file open, like this:

tail -f "$serverlog" | do_all_processing_here

Note that grep "[INFO]" doesn't do what you intend; instead, it matches lines that contain any of the characters I, N, F, or O. You probably meant grep -F '[INFO]' — the -F causes grep to treat your pattern as a fixed string rather than a regular expression. Then, your structure would be:

tail -f "$serverlog" | grep -F '[INFO]' | do_more_processing_here

I'm going to guess that [INFO] would appear in the third field of your server log. If so, the efficient solution would be...

tail -f "$serverlog" | \
while read date time severity player message ; do
 case "$severity" in
 \[INFO\])
 case "$message" in
 *joined the game*)
 echo "$player $date $time" >> "$onlinefile"
 awk -v player="$player" '1ドル == player { print NR }' | \
 while read lineno ; do
 sed -i "${lineno}d" "$offlinefile"
 done
 ;;
 *left the game*)
 echo "$player $date $time" >> "$offlinefile"
 awk -v player="$player" '1ドル == player { print NR }' | \
 while read lineno ; do
 sed -i "${lineno}d" "$onlinefile"
 done
 ;;
 esac # case $message
 ;;
 esac # case $severity
done

It's also possible to skip awk and edit $offlinefile and $onlinefile directly with

sed -i "/^$player /d" "$offlinefile"

but there could be a vulnerability if $player contained special characters such as .*.

lang-bash

AltStyle によって変換されたページ (->オリジナル) /