1

Need some opinion on my scripting. I have some files like below format:-

-rw-r--r-- 1 root root 0 Apr 12 15:56 hostdata_mm-xxx1_2018_04_03.csv
-rw-r--r-- 1 root root 0 Apr 12 15:56 hostdata_mm-xxx1_2018_04_04.csv
-rw-r--r-- 1 root root 0 Apr 12 15:56 hostdata_mm-xxx1_2018_04_05.csv
-rw-r--r-- 1 root root 0 Apr 12 15:56 hostdata_mm-xxx1_2018_04_06.csv
-rw-r--r-- 1 root root 0 Apr 12 15:56 hostdata_mm-xxx1_2018_04_07.csv
-rw-r--r-- 1 root root 0 Apr 12 15:56 hostdata_mm-xxx1_2018_04_08.csv
-rw-r--r-- 1 root root 0 Apr 12 15:56 hostdata_mm-xxx1_2018_04_09.csv
-rw-r--r-- 1 root root 0 Apr 12 15:56 hostdata_mm-xxx1_2018_04_10.csv

I need to have 1 file only which is yesterday's data, so, my script is like this:-

#!/bin/bash

set -x
wd=/root/test
yest=$(date -d "yesterday" '+%Y_%m_%d')

cd $wd
for f in *[0-9][0-9][0-9][0-9]_[0-9][0-9]_[0-9][0-9].csv; do
date=${f#*}
date=${date%.csv}
date=`echo $date | rev`
date=${date:0:10}
date=`echo $date | rev`
(( $date < $yest )) && rm $f
done

However, I got this error

/usr/local/bin/testdelfile: line 15: ((: 2018_04_03: value too great for base (error token is "2018_04_03")
/usr/local/bin/testdelfile: line 15: ((: 2018_04_04: value too great for base (error token is "2018_04_04")
/usr/local/bin/testdelfile: line 15: ((: 2018_04_05: value too great for base (error token is "2018_04_05")
/usr/local/bin/testdelfile: line 15: ((: 2018_04_06: value too great for base (error token is "2018_04_06")
/usr/local/bin/testdelfile: line 15: ((: 2018_04_07: value too great for base (error token is "2018_04_07")
/usr/local/bin/testdelfile: line 15: ((: 2018_04_08: value too great for base (error token is "2018_04_08")
/usr/local/bin/testdelfile: line 15: ((: 2018_04_09: value too great for base (error token is "2018_04_09")
/usr/local/bin/testdelfile: line 15: ((: 2018_04_10: value too great for base (error token is "2018_04_10")

Here is the debug mode

+ for f in '*[0-9][0-9][0-9][0-9]_[0-9][0-9]_[0-9][0-9].csv'
+ date=hostdata_mm-xxx1_2018_04_10.csv
+ date=hostdata_mm-xxx1_2018_04_10
++ echo hostdata_mm-xxx1_2018_04_10
++ rev
+ date=01_40_8102_1kmc-ym_atadtsoh
+ date=01_40_8102
++ echo 01_40_8102
++ rev
+ date=2018_04_10
+ ((  2018_04_10 < 2018_04_12  ))
/usr/local/bin/testdelfile: line 15: ((: 2018_04_10: value too great for base (error token is "2018_04_10")

please advice

2 Answers2

1

(( ... )) operator in bash expects arithmetic value. The 2018_04_10 is a string and so you get an error. Use [[ ... ]] to do string comparison.

However with date, I would advice to convert to numerical timestamp date +%s in order to compare it with (( ... )).

You can change your script to have:

yest=$(date -d "yesterday" '+%s')
for f in *[0-9][0-9][0-9][0-9]_[0-9][0-9]_[0-9][0-9].csv; do
   date=$(sed -r 's/.*([0-9]{4})_([0-9]{2})_([0-9]{2}).csv/\1-\2-\3/' <<< $f | xargs date +%s -d)
   (( $date < $yest )) && rm $f
done
oliv
  • 496
  • 4
  • 4
  • Tried your script but it deletes all of the files. What I did was:- 1. Add (touch) one more file in the same directory called hostdata_mm-xxx1_2018_04_12.csv (yesterday's file based on its name not timestamp) 2. run your script – Diligent Bug Apr 13 '18 at 08:14
  • Issue resolved after changing the operator in my original script. Thanks! – Diligent Bug Apr 16 '18 at 03:29
1

The problem with the script is that an inappropriate operator is used for the string comparison. Just replace (( ... )) with [[ ... ]] in 14th line and the script will work fine.

More info can be found at http://tldp.org/LDP/abs/html/comparison-ops.html

I would like to suggest a simpler solution. With find you can exclude by name the file you want to keep and then delete the other files in the directory:

find . -not -name "hostdata_mm-xxx1_$(date -d 'yesterday' '+%Y_%m_%d').csv" -type f -exec rm {} ";"
GeorgiY
  • 21
  • 2
  • while your answer might be useful to other visitors, the OP asked to identify the bug in his script. Could you also explain what is wrong with his script? – Luca Gibelli Apr 13 '18 at 06:57
  • @GeorgiY, issue resolved after changing the operator. Thanks! BTW, your simplified command removes all files as it checks timestamp of file creation instead of timestamp on file name. – Diligent Bug Apr 16 '18 at 03:27
  • @user240614 ОК. Could you recheck the command? The command use -name argument rather the -ctime/mtime argument. The latter are used to find files by date of crate/modification. – GeorgiY Apr 16 '18 at 07:43