Hello,

I have one "tar.Z" file. Objective is to unzip it by shell script and check the date.

  • archive: filename_20140103_1540.tar.Z

     #!/bin/bash
    cd $REP_DATAS/path
    u=$(date +%u)
    if [ ${u} -eq 1 ] ; then        
    dateQ=`date --date='-3 day' +'%Y%m%d_%H%m'`
    else
    dateQ=`date --date='-1 day' +'%Y%m%d_%H%m'`
    fi
    tar xvf filename_"dateQ".tar.Z
    
error:

tar: Error is not recoverable: exiting now

THANKS IN ADVANCED.

Recommended Answers

All 14 Replies

Add $ to "dateQ" otherwise you get filename_dateQ.tar.Z instead of the date & time string:

tar xvf filename_"$dateQ".tar.Z

Yes, you are right. Good remark.

but still there is same error.

thanks.

Ok, so the error is file not found or something else? Currently you're not checking if the file is available, try to add a check, and change the extracting command, an example:

file=filename_$dateQ.tar.Z

if [ -f $file] ; then
zcat $file | tar xvf -
else
echo "$file not found"
fi

It is good idea. My file name is difficult to handle in shell script and check the date.
I need to verify that it should not be 4 days before.
For example, if its monday than it must be the date of Friday, not date of thursday.
I hope i am clear.

#!/bin/bash
filename = 'my_file'
file = $filename.$dateQ.tar
echo $file.tar
if [ -f $file]; then
zcat $file | tar xvf -
else
echo "$file not found"
fi
tar xvf my_file_20140106_1655.tar.Z

syntax error: unexpected end of file

You can change the approach: with $dateQ you set also the time segment %H%M, not only the day, so if you search for a file of 20140106 you find it only if you match also the hour and the minute segment, i.e.: 1655.

If you cannot avoid the time segment in filenames, then you can change $dateQ to generate only the date segment, so:

dateQ=`date --date='-3 day' +'%Y%m%d'`

instead of:

dateQ=`date --date='-3 day' +'%Y%m%d_%H%M'`

and use it as a regular expression to match the file:

#!/bin/bash
cd $REP_DATAS/path
u=$(date +%u)

if [ ${u} -eq 1 ] ; then
dateQ=`date --date='-3 day' +'%Y%m%d'`
else
dateQ=`date --date='-1 day' +'%Y%m%d'`
fi

list='*.tar.Z'
for file in $list
do
    if [[ $file =~ $dateQ ]]
    then
        zcat $file | tar xvf -
    fi
done

Where list can also be limited to the last 10 modified files, so the script does not have to loop against all files:

list='ls -t *.tar.Z | head -n 10'

You can change it as you prefer.

Note a part: you were using %H%m which will print hourmonth not hourminutes, so use %M to get the minutes.

Thanks.

Is it possible to write only "%Y%m%d"? I tried your code. Error on line 6

line 6: [: -eq: unary operator expected

I have file of 3rd January for the moment.

It seems it is comparing with current date.

my_file_20140103_1540
 =:              ERROR: cannot open = (No such file or directory)
.20140108_1557: ERROR: cannot open .20140108_1557 (No such file or directory)

I need to make it in general. It should work minimum once evenif the file is two weeks old. The objective is just to display the date of file, if its not new, it will disply in red message as alert that file is very old.

line 6: [: -eq: unary operator expected

The error means $u is missing or is null, so this fails:

if [ ${u} -eq 1 ] ; then

In my example this is defined by:

u=$(date +%u)

So it should work fine.

It should work minimum once evenif the file is two weeks old. The objective is just to display the date of file, if its not new, it will disply in red message as alert that file is very old.

This is very different from what you were asking in your previouses posts.

To get files with a date in the filename change the pattern to match the numbers, something like:

dateQ='([0-9])'

Or:

dateQ='20[0-9]{2}(0[1-9]|1[0-2])([0-2][0-9]|3[0-1])'

An updated version of the script:

#!/bin/bash
cd $REP_DATAS/path

dateQ='20[0-9]{2}(0[1-9]|1[0-2])([0-2][0-9]|3[0-1])'

list='*.tar.Z'

for file in $list
do
    if [[ $file =~ $dateQ ]]
    then
        echo $file
    fi
done

If you still have problems post your updated script and explain exactly your goals.

OK.
There is no error messgae BUT it is not really working. There are 7 files in the archive .tar.Z
It is not extracting files.
We are very close to the output but need little modification.

cd $REP_DATAS/path

    u=$(date +%u)

        if [ ${u} -eq 1 ] ; then
        dateQ=`date --date='-3 day' +'%Y%m%d'`
        else
        dateQ=`date --date='-1 day' +'%Y%m%d'`
        fi

        list='ls -t *.tar.Z'
        for file in $list
        do
        if [[ $file =~ $dateQ ]]
        then
        zcat $file | tar xvf -
        fi
        done

If you still have problems post your updated script and explain exactly your goals.

Superlike..!

Yes, it is working after this change with date
dateQ='20[0-9]{2}(0[1-9]|1[0-2])([0-2][0-9]|3[0-1])'

In fact, my goal is to check the date of file.
There are 7 files inside the .tar.Z file. With that 7 files i need to do update operation in my database.

Normally, everyday (Monday to Friday) i will receive new file with respective date. I need to check the date and display the date of file.
For example, if one day i have not received file in that case, i need to use previous file.

Simple example:
Day 1: 09 Jan 2014
I have received the .tar.Z file --> extract --> update operation --> Mesg
"File has received 09 Jan 2014"
Day 2: 10 Jan 2014
I have received the .tar.Z file --> extract --> update operation --> Mesg
"File has received 10 Jan 2014"
Note: DELETE FILE OF 9th Jan
Day 3: 13 Jan 2014
I have NO Files.

So, i have to use yesterdays file and repeat the same procedure with ALERT MESG.

"File has received 10 Jan 2014" (in RED)
There should be one file ALWAYS available to do update operation, no matter which date.

I hope i am clear.

that's why i wrote

if [ ${u} -eq 1 ] ; then
dateQ=`date --date='-3 day' +'%Y%m%d'`
else
dateQ=`date --date='-1 day' +'%Y%m%d'`
fi

Thanks in advanced for your suggestion / comments.

Once again thanks. :)

It means that you have to compare the date string with the one in the filenames and get the most recent. I suppose you cannot consider ctime/mtime/atime, correct? Because if one of the old files is changed it will prompt ahead.

I'm not good with bash scripts but here's an example that seems to work fine:

#!/bin/bash

cd $REP_DATAS/path

current=$(date -u --date='now' '+%F %H:%M')
file_is_old=3
limit=$file_is_old
result=''

dateQ='20[0-9]{2}(0[1-9]|1[0-2])([0-2][0-9]|3[0-1])_([0-9]{4})'
list='*.tar.Z'

for file in $list
    do
        if [[ $file =~ $dateQ ]]
        then

            match=$BASH_REMATCH

            year=${match:0:4}
            month=${match:4:2}
            day=${match:6:2}
            hour=${match:9:2}
            minute=${match:11:2}

            check=$(date -u --date="$year-$month-$day $hour:$minute" '+%F %H:%M')

            diff ()
            {
                printf '%s' $(($(date -u --date="$current" +%s) - $(date -u --date="$check" +%s)))
            }

            fileage=$(($(diff) / 60 / 60 / 24))

            if [ $fileage -le $limit ]
            then
                let limit=fileage
                export result="$file"
            else
                continue
            fi

            if [ $fileage -ge $file_is_old ]
            then
                result="-en \E[47;31m\033[1m Warning: $file is old \033[0m\n"
                tput sgr0
            else
                result=$file
            fi

        fi
    done

echo $result

I'm sure this can be rewritten a lot better, so before using it wait for other suggestions or, better, check the bash documentation.

Reference:

Good luck! :)

I am not sure for this but i tried:

  u=$(date +%u)
        if [ ${u} -eq 1 ] ; then        
        dateQ=`date --date='-3 day' +'%Y%m%d'`
        else
        dateQ=`date --date='-1 day' +'%Y%m%d'`
        fi

        zcat my_file_"$dateQ"*.tar.Z | tar xvf -

Thanks for your help.

Fianlly, it works :)

cd $file/path

        u=$(date +%u)
        if [ ${u} -eq 1 ] ; then        
        dateQ=`date --date='-3 day' +'%Y%m%d'`
        else
        dateQ=`date --date='-1 day' +'%Y%m%d'`
        fi

        zcat my_file_"$dateQ"*.tar.Z | tar xvf -

Thank you all for your time and input. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.