Vlad Stratulat
Vlad Stratulat

Reputation: 1296

Variables in Bash

I have the following in my bash script

EXTENSIONS=(php css js)

Then I have this

declare FILE_TYPES
for EXTENSION in ${EXTENSIONS[@]}; do
  FILE_TYPES+=("'*.${EXTENSION}'")
done

If I echo ${FILE_TYPES[@]}, I get this

'*.php' '*.css' '*.js'

I want to create a LIST variable which will create a list of files modified by Git of certain extension. It should look like this:

git diff --name-only --cached --diff-filter=ACMR -- '*.php' '*.css' '*.js'

Note that it will not work if I run command like this:

git diff --name-only --cached --diff-filter=ACMR -- *.php *.css *.js

In my bash script I'm trying this option

LIST=$( git diff --name-only --cached --diff-filter=ACMR -- ${FILE_TYPES[@]})

But it doesn't work. I have a feeling that it creates the second version of command.

Any help would be appreciated!

Upvotes: 1

Views: 414

Answers (4)

Léa Gris
Léa Gris

Reputation: 19545

An iteration is not needed because creating files patterns from extensions is done all at once with "${extensions[@]/#/*.}" which replaces the start of each extensions array entries with *..

#!/usr/bin/env bash

extensions=(php css js)

# Proper way to populate the list array from the output of git-diff
mapfile -t list < <(
  git diff --name-only --cached --diff-filter=ACMR -- "${extensions[@]/#/*.}"
)

For obsolete versions of bash without mapfile:

#!/usr/bin/env bash

extensions=(php css js)

IFS=$'\n' read -r -d '' -a list < <(
  git diff --name-only --cached --diff-filter=ACMR -- "${extensions[@]/#/*.}"
)

Upvotes: 3

nntrn
nntrn

Reputation: 614

Not sure what you're trying to do with git diff-filter but you can wrap variables in an array using printf

$ EXTENSIONS=(php css js)
$ printf "'*.%s' " $EXTENSIONS
'*.php' '*.css' '*.js'

Upvotes: 1

chepner
chepner

Reputation: 531055

You don't need the single quotes in the array values; those would be literal quotes, not syntactic quotes. Simply ensuring that a literal * appears in the value is enough; then you want to quote the expansion of the array in order to prevent file name expansion on the result.

EXTENSIONS=(php css js)
declare -a FILE_TYPES

for ext in "${EXTENSIONS[@]}"; do
    FILE_TYPES+=( "*.$ext" )
done

LIST=$( git diff --name-only --cached --diff-filter=ACMR -- "${FILE_TYPES[@]}" )

Upvotes: 3

user000001
user000001

Reputation: 33317

Try like this:

declare FILE_TYPES
for EXTENSION in "${EXTENSIONS[@]}"; do
  FILE_TYPES+=("*.${EXTENSION}")
done
LIST=$( git diff --name-only --cached --diff-filter=ACMR -- "${FILE_TYPES[@]}")

Note the removal of the single quotes in the FILE_TYPES definition and the addition of the double quotes in "${FILE_TYPES[@]}" expansion. Also the usage of "${EXTENSIONS[@]}" needs also double quotes.

Upvotes: 2

Related Questions