Find filenames with number in name lower than 1950

1.1k views Asked by At

I have the following problem: I have a list of files like this

File256name.txt
File307list.cvs
File2014text.xls

I would use the command "find" to only find files with number in the name lower than 1950 so as the previous list I would only have these files listed

File256name.txt
File307list.cvs

I tried this command

find . -type f  \( -iname '*[1-9][0-9][0-9]*' \)

but it will display also files containing number in the name >1950

As additional indication all files can have different filenames and extensions and the position of the number is unpredictable...I'm looking for a simple command to use with find (for me is mandatory to use find) by including a formula to select only files that contains numbers lower than 1950

Also consider the limitation of my linux version that is BusyBox v1.16.1

Thanks for your help

3

There are 3 answers

9
urzeit On BEST ANSWER

You'll need to use a regex that will differenciate the decade in respect to century:

.*(19[5-9][0-9]|[2-9][0-9]{3}).*

(This will find 4-digit numbers greater than or equal 1950).

Using this regex you may use the negate option of find to get files with no number >= 1950. To eliminate files without any number, use a second criteria.

I've not tested this with find, but the regex you use allows for 1000 < 1950.

Edit:

The full command:

find . -regextype posix-egrep -regex '.*[0-9].*' \! -regex '.*(19[5-9][0-9]|[2-9][0-9]{3}).*'

With busybox's find some more escaping is necessary:

find . -regex '.*[0-9].*' \! -regex '.*\(19[5-9][0-9]\|[2-9][0-9]\{3\}\).*'
6
AudioBubble On

Pipe into (G)awk

find . -type f | awk 'match($0,/[0-9]+/,a)&&a[0]<1950'

This only matches files with numbers in, and then checks if the number is below 1950 and prints. it will work for file with only 1 digit or with 4 and also with leading zeros.

2
David C. Rankin On

It can be done simply in bash with character classes and substring removal:

#!/bin/bash

for i in "$@"; do
    ffn="${i##*/}"
    num="${ffn//[^0-9]/}"
    [ "$num" -le 1950 ] && echo "$i => $num"
done

input:

File1949text.doc
File1950text.doc
File1951text.dat
File2014text.xls
File256name.txt
File307list.cvs

output:

$ bash ../fn1950.sh File*
File1949text.doc => 1949
File1950text.doc => 1950
File256name.txt => 256
File307list.cvs => 307