Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .