Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a list of files inside a directory and I want to make a bash script which uses a regular expression to check if every file name inside it has this syntax:

xxxx_xxxx_xx_xx

Where x are numbers.

Edit: I only need with the regex

share|improve this question

2 Answers 2

up vote 8 down vote accepted

How about

#/usr/bin/env bash
for f in *
do
  [[ $f =~ [0-9]{4}_[0-9]{4}_[0-9]{2}_[0-9]{2} ]] || 
    echo "File $f does not match"
done

The regular expression checks for any digit ([0-9]). The numbers in curly braces are the number of repetitions so [0-9]{4} will match any 4 digits.

I would recommend you don't use bash for this but find instead. It will probably be faster, and it is certainly more portable (not all shells can deal with regular expressions):

find -regextype posix-egrep -not -regex '\./[0-9]{4}_[0-9]{4}_[0-9]{2}_[0-9]{2}'
share|improve this answer
    
I can’t construct a scenario that causes your find command to break, but I still believe (on general principles) that the regex should probably be quoted, for safety. –  Scott Jul 11 '14 at 14:50
    
@Scott I tend to agree with such precautionary quoting but I don't know of any shell that would choke on that. Still, as you said, better safe than sorry. Quotes added. –  terdon Jul 11 '14 at 15:31
    
OK, I had my n+1 th injection of caffeine, and I figured it out. It’s not an issue of the shell choking, per se. If there is a file in the current directory with a name like 5{4}_3{4}_0{2}_9{2} (and you don’t have shell globbing turned off), then \./[0-9]{4}_[0-9]{4}_[0-9]{2}_[0-9]{2} (your regex) will expand to ./5{4}_3{4}_0{2}_9{2}, and your find will match only ./5555_3333_00_99 (if it exists). … … (BTW, 5309 is the last four digits of Jenny’s phone number.) –  Scott Jul 11 '14 at 15:50
    
@Scott ah, yes, well found! Who's Jenny? Or should I not ask? –  terdon Jul 11 '14 at 16:29
    
Seriously? Oh, I see; you don’t live in a primarily English-speaking country. Here you go. –  Scott Jul 11 '14 at 16:33

It’s clunky, but this should be very portable:

#!/bin/sh
for x in *
do
    case "$x" in
        [0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]_[0-9][0-9]_[0-9][0-9])
            echo "$x matches"
            ;;
        *)
            echo "$x  doesn’t match"
    esac
done
#                       And, to be annoyingly complete,
for x in .*
do
    echo "$x  doesn’t match"
done
share|improve this answer
    
Same regex i used, btw i think that the solution provided by @terdon is cleaner. Thanks anyway! –  Federico Ponzi Jul 11 '14 at 18:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.