'Identify the files year wise and delete from a dir in unix

I need to list out the files which are created in a specific year and then to delete the files. year should be the input.

i tried with date it is working for me. but not able to covert that date to year for comparison in loop to get the list of files.

Below code is giving 05/07 files. but want to list out the files which are created in 2022,2021,etc.,

    for file in /tmp/abc*txt ; do
    [ "$(date -I -r "$file")" == "2022-05-07" ] && ls -lstr "$file"
done


Solution 1:[1]

If you end up doing ls -l anyway, you might just parse the date information from the output. (However, generally don't use ls in scripts.)

ls -ltr | awk '$8 ~ /^202[01]$/'

date -r is not portable, though if you have it, you could do

for file in /tmp/abc*txt ; do
    case $(date -I -r "$file") in
        2020-* | 2021-* ) ls -l "$file";;
    esac
done

(The -t and -r flags to ls have no meaning when you are listing a single file anyway.)

If you don't, the tool of choice would be stat, but it too has portability issues; the precise options to get the information you want will vary between platforms. On Linux, try

for file in /tmp/abc*txt ; do
    case $(LC_ALL=C stat -c %y "$file") in
        2020-* | 2021-* ) ls -l "$file";;
    esac
done

On BSD (including MacOS) try stat -f %Sm -t %Y "$file" to get just the year.

If you need proper portability, perhaps look for a scripting language with wide support, such as Perl or Python. The stat() system call is the fundamental resource for getting metainformation about a file. The find command also has some features for finding files by age, though its default behavior is to traverse subdirectories, too (you can inhibit that with -maxdepth 1; but then the options to select files by age are again not entirely POSIX portable).

Solution 2:[2]

To list out files which were last modified in a specific year and then to delete those files, you could use a combination of the find -newer and touch commands:

# given a year as input
year=2022
stampdir=$(mktemp -d)
touch -t ${year}01010000 "$stampdir"/beginning
touch -t $((year+1))01010000 "$stampdir"/end
find /tmp -name 'abc*txt' -type f -newer "$stampdir/beginning" ! -newer "$stampdir/end" -print -delete
rm -r "$stampdir"

First, create a temporary working directory to store the timestamp files; we don't want the find command to accidentally find them. Be careful here; mktemp will probably create a directory in /tmp; this use-case is safe only because we're naming the timestamp files such that they don't match the "abc*txt" pattern from the question.

Next, create bordering timestamp files with the touch command: one that is the newest date in the year, named "beginning", and another for the newest date of the next year, named "end".

Then run the find command; here's the breakdown:

  • start in /tmp (from the question)
  • files named with the 'abc*txt' pattern (from the question)
  • only files (not directories, etc -- from the question)
  • newer than the beginning timestamp file
  • not newer (i.e. older) than the end timestamp file
  • if found, print the filename and then delete it

Finally, clean up the temporary working directory that we created.

Solution 3:[3]

Try this:

For checking which files are picked up:

echo -e "Give Year :"

read yr

ls -ltr /tmp | grep "^-" |grep -v ":" | grep $yr | awk -F " " '{ print $9;}'

** You can replace { print $9 ;} with { rm $9; } in the above command for deleting the picked files

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jeff Schaller
Solution 3 ns.raju