2

In my linux folder there are following files:

abc.txt
test.log
kkk.war
Type1_20160814.xml
Type1_20160624.xml
Type1_20160703.xml
Type1_20160503.xml

I want to gzip Type1 files that NOT belongs to current month, which is August (i can't use mtime).

Expected Result, the following files gzip-ed:

Type1_20160624.xml
Type1_20160703.xml
Type1_20160503.xml

Actually i tried:

files=$(find . -maxdepth 1 -mindepth 1 -not -type f -name "Type1_201608*.xml")
gzip -5 ${files[@]}

BUT, it also gzip files that not Type1(like following), how can i avoid that?

abc.txt
test.log
kkk.war
hades
  • 279

3 Answers3

2
find . -maxdepth 1 -mindepth 1 -not -type f -name "Type1_201608*.xml"

This means: for the files in the current directory (. -maxdepth 1 -mindepth 1), list the files that are not regular files (-not -type f), and that have a name matching "Type1_201608*.xml.

Since you want to list only files that match Type1_*.xml, your command is going to have to include this pattern somehere! And since you want to act on regular files, don't negate -type f.

find . -maxdepth 1 -mindepth 1 -type f -name "Type1_*.xml" ! -name "Type1_201608*.xml"

Don't parse the output of find. Use -exec, that's what it's for.

find . -maxdepth 1 -mindepth 1 -type f -name "Type1_*.xml" ! -name "Type1_201608*.xml" -exec gzip -5 {} +

With modern shells, if the pattern Type1_*.xml doesn't match any directory or any symbolic link that you want to exclude, you don't need find for this. You can use ksh extended glob patterns, which are also available in bash.

shopt -s extglob
gzip -5 Type1_!(201608*).xml

In zsh, you can enable ksh extended glob patterns, but you can also use zsh's own.

setopt extended_glob
gzip -5 Type1_*.xml~Type1_201608*

Or

gzip -5 Type1_(^201608*).xml

And in zsh, if you want to ensure that only regular files are matched, you can use a glob qualifier.

setopt extended_glob
gzip -5 Type1_(^201608*).xml(.)
1

Using bash with the extglob shell option set:

$ shopt -s extglob

$ echo Type1_????!(08)??.xml Type1_20160503.xml Type1_20160624.xml Type1_20160703.xml

$ gzip Type1_????!(08)??.xml

The !(something) pattern will match anything except something.

This also works in ksh (where that syntax comes from) without setting any non-default option.

Kusalananda
  • 333,661
0

I tried executing below command in the working directory and all the files got gziped.

to execute in same directory

gzip -f $(ls -l | grep Type1 | grep -v $(date +%Y%m) | awk '{print $NF}')

to execute from different directory in ls we need to add the folder name as argument

gzip -5 $(ls -lrt -d -1 test/* | grep Type1 | grep -v $(date +%Y%m) | awk '{print $NF}')

Recieved output

Type1_20160102.xml.gz

Type1_20160105.xml.gz

Type1_20160624.xml.gz

Type1_20160703.xml.gz

Type1_20160704.xml.gz

Type1_20160705.xml.gz

this command's will zip all the files in directory name Type1 excluding current month files

upkar
  • 326