开发者

How to capture results of regex and replace patterns in bash

Bash scripting does my head in. I have searched for regex assignment, but not really finding answers I understand.

I have files in a directory. I need to loo开发者_StackOverflow社区p through the files and check if they fit certain criteria. File names under a certain sequence need to have their sequence increased. Those over a certain sequence need to trigger an alert.

I have pseudo code and need help turning it into correct bash syntax:

#!/bin/sh

function check_file()
{
    # example file name "LOG_20101031144515_001.csv"
    filename=$1

    # attempt to get the sequence (ex. 001) part of file

    # if sequence is greater than 003, then raise alert

    # else change file name to next sequence (ex. LOG_20101031144515_002.csv)
}

for i in `ls -Ar`; do check_file $i; done;

If PHP were an option, I could do the following:

function check_file($file){
    //example file 'LOG_20101031144515_001.csv';

    $parts = explode('.',$file);
    preg_match('/\d{3}$/', $parts[0], $matches);
    if ($matches){
        $sequence = $matches[0];
        $seq      = intval($sequence);

        if ($seq > 3){
            // do some code to fire alert (ex. email webmaster)
        }
        else{
            // rename file with new sequence
            $new_seq  = sprintf('%03d', ++$seq);
            $new_file = str_replace("_$sequence", "_$new_seq", $file);
            rename($file, $new_file);
        }
    }
}

So long story short, I'm hoping someone can help port the PHP check_file function to the bash equivalent.

Thank you


First of all, your question is tagged [bash], but your shebang is #!/bin/sh. I'm going to assume Bash.

#!/bin/bash
function check_file()
{
    # example file name "LOG_20101031144515_001.csv"
    filename=$1

    # attempt to get the sequence (ex. 001) part of file

    seq=${filename%.csv}
    seq=${seq##*_}

    # if sequence is greater than 003, then raise alert

    if (( 10#$seq > 3 ))
    then
        echo "Alert!"
    else
        # else change file name to next sequence (ex. LOG_20101031144515_002.csv)
        printf -v newseq "%03d" $((seq + 1))
        echo "${filename/$seq/$newseq}" # or you could set a variable or do a mv
    fi
}


PHP IS an option. If you master PHP, you can run it from shell. Run

php myfile.php

and get the output right into console. If the PHP file is executable and begins with

#!/path/to/php/executable

then you can run

./myfile.php

I'm no big expert in bash programming, but in order to obtain the list of files that match a certain patter you can use the command

ls -l | grep "pattern_unquoted"

I suggest you to go for the PHP ;-)


A different take on the problem:

#!/bin/sh

YOUR_MAX_SEQ=3

find /path/to/files -maxdepth 1 -name 'LOG_*.csv' -print \
  | sed -e 's/\.csv$//' \
  | awk -F_ '$3 > SEQ { print }' SEQ=$YOUR_MAX_SEQ

Brief explanation:

  • Find all files in /path/to/files matching LOG_*.csv
  • Chop the .csv off the end of each line
  • Using _ as a separator, print lines where the third field is greater than $YOUR_MAX_SEQ

This will leave you with a list of the files that met your criteria. Optionally, you could pipe the output through sed to stick the .csv back on.

If you're comfortable with PHP, you'd probably be comfortable with Perl, too.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜