DomainsFeatured
DomainsFeatured

Reputation: 1506

How To Delete A File Every X Times A Script Is Run - Manage A Log File From Inside A Script?

I would normally just schedule this as a cron job or script, however, I would like to delete a log file (it's constantly appended to every time a script runs) only after 50 times.

Needed Inside The Script:

The thing is, since the script does not run consistently, it has be to be implemented within the script itself. Please note: for various reasons, I need this inside the script.

What I Was Trying:

I was thinking of setting a variable to increment, outputting it to a file and then having the script read that file every time. Then, if that value is greater than X, remove the file. That portion of the code would be a grep or awk statement.

Anyone know an easy, better way to do this? Your positive input is highly appreciated.

Upvotes: 1

Views: 164

Answers (4)

user3439894
user3439894

Reputation: 7555

Using sed in the code below it will increment x by 1 within the script, each time the script is run, up to 50 and then set x back to 1. You can set the command to process the logfile in the else branch of the if statement along with whatever other code you want to run in each branch.

#!/bin/bash

x=1
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi

Here I run the script to show x gets incremented and reset back to 1 after 50 runs:

$ cat testscript
#!/bin/bash

x=1
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi
$ ./testscript
$ cat testscript
#!/bin/bash

x=2
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi
$

As you can see x=1 has became x=2 within the script.

I now manually set x=2 to x=50 and saved the script to show it resets to x=1.

$ cat testscript
#!/bin/bash

x=50
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi
$ ./testscript
$ cat testscript
#!/bin/bash

x=1
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi
$ 

Upvotes: 1

DomainsFeatured
DomainsFeatured

Reputation: 1506

As mentioned, my main requirement is to do this inside the script or in-line. As @EvansWinner mentioned, I can manage the file by using properties like the file size or age. However, I went with something even more simple, using number of lines.

sed -i '100000,$ d' file.txt

Thus, I don't have to worry about how many times it runs. Hopefully, for anyone who is trying to also delete a file every x times, within a script, this will help you look at the file properties and how they can be managed using size, age or as I have used, number of lines. These solutions are much more portable than creating programs or packages that are required on other systems.

Upvotes: 0

James Brown
James Brown

Reputation: 37404

Since the Gnu awk v.4.1 the inplace edit has been available (see awk save modifications in place) so, you could store the counter to your awk script variable and use the awk script to edit itself and decrement the counter varible like this:

$ cat program.awk
BEGIN {
    this=5                                  # the counter variable
}
/this=[0-9]+/ {                             # if counter (this=5) matches
    if(this==0)                             # if counter is down to 0...
        ;                                   # ... do what you need to do
    split($0,a,"=")                         # split "this=5" by the "="
    sub(/=[0-9]+$/,"=" (a[2]==0?5:a[2]-1))  # decrement it or if 0 set to 5 again
}
1                                           # print

Run it:

$ awk -i inplace -f program.awk program.awk
$ head -3 program.awk
BEGIN {
    this=4                                  # the counter variable
}

Basically you run program.awk that changes one record in program.awk inplace and once counter hits 0, the if gets executed.

Upvotes: 2

Mark Setchell
Mark Setchell

Reputation: 207425

You could use xattr to associate arbitrary metadata with a file, like this:

touch a.txt                # Create file
xattr -w runs 1 a.txt      # Set run count to 1
xattr -p runs a.txt        # Print run count
1

xattr -w runs 49 a.txt     # Change value
xattr -l a.txt             # List all attributes
runs: 49

The beauty of that is it doesn't show up in grep or when looking at the file with normal tools.

Note that not all filesystems (e.g. Microsoft FAT) will support xattr.

Upvotes: 2

Related Questions