1

Being someone who is new to bash scripting, I decided to try and unit test my current project from the start. Currently I have a problem with a single line of code. with it I'm trying to search the directory output_json for the files that match a regex.

before I show any code here is the directory structure that the script runs in:

full path to working directory:

C:\Users\chris\Google Drive\code projects\Replacement Program for Chile Letters\tests\general bash unit tests.

directory tree of current working directory:

├───general bash unit tests  <--(working dir)
    ├───node_fake_returns
    └───output_json
        ├───email_data-1.json
        ├───email_data-2.json
        ├───email_data-3.json
        ├───variable_data-1.json 
        ├───variable_data-2.json
        └───variable_data-3.json

the line that I'm trying to use to return an array containing all the filenames of the variable_data files is as follows:

local contentVars=$(find "./output_json" -regextype posix-extended \
  -regex '.*/output_json/variable_data-\d+.json')

Here's is the entire function used to unit test just in case I having something else wrong with the unit test. note the assertion function is from shunit2.

testFileNameCapturing() {

    local contentVars=$(find "./output_json" -regextype posix-extended \
      -regex '.*/output_json/variable_data-\d+.json')
    local emailDataVars=$(find "./output_json" -regextype posix-extended \
      -regex 'variable_data-\d+.json')

    assertTrue "[ $contentVars == './output_json/variable_data-1.json' ]"
}

I'm sure this is just a small syntax error, but it really has stalled me for a majority of the day. Any help would be great!

Alex Harvey
  • 14,494
  • 5
  • 61
  • 97
Leviathan_the_Great
  • 429
  • 1
  • 5
  • 14
  • Someone else had answered about the regex and they seem to have deleted their answer. I agree, there is something strange about the regex. I'll update my answer. – Alex Harvey Apr 21 '19 at 13:24

1 Answers1

1

I have 2 parts. On your regex question, and on simplifying your unit test code.


On the regex:

On the regex, I agree that there is something odd about the implementation of GNU find's handling of regex.

Documentation for the GNU find regex is found here.

If you use the default GNU find regular expression, you can write this:

▶ find ./output_json -regex './output_json/variable_data-[0-9]+\.json'                       
./output_json/variable_data-1.json
./output_json/variable_data-3.json
./output_json/variable_data-2.json

Using POSIX-extended, however, I would, like you, expect \d to match a digit. It works here for instance.

But in the GNU find posix-extended regex docs there is no mention of \d, only [[:digit:]].

Thus, this works:

▶ find "./output_json" -regextype posix-extended -regex './output_json/variable_data-[[:digit:]]+\.json'
./output_json/variable_data-1.json
./output_json/variable_data-3.json
./output_json/variable_data-2.json

On fixing your code:

I think you should simplify your code and avoid the regex altogether, and just use a glob pattern:

local contentVars=$(find ./output_json -name "variable_data-[0-9]*.json")

This is simpler, easier to understand, and doesn't rely on a GNU extension, thus is more portable.

That's not going to return an array, however, but a newline-separated string, and the assertion you make:

assertTrue "[ $contentVars == './output_json/variable_data-1.json' ]"

should fail. Perhaps try:

testFileNameCapturing() {
  local contentVars=$(find output_json/ -name "variable_data-[0-9]*.json")

  local expected="output_json/variable_data-1.json
output_json/variable_data-3.json
output_json/variable_data-2.json"

  assertEquals "$expected" "$contentVars"
}

. shunit2

Output:

testFileNameCapturing

Ran 1 test.

OK
Alex Harvey
  • 14,494
  • 5
  • 61
  • 97