0

i have a bash/shell script and want to store a command output in a variable (EXCLUDE_PATTERN) and the command itself contains also variables (FOLDERS and BUPATH).

the goal with this command is to replace the spaces in the variable FOLDERS with " --exclude="$BUPATH for use in an tar command

if have defined the following variables in the script:

FOLDERS='folder1 folder2 folder3'
BUPATH='/opt/mypath'
CONFIG_BACKUP="/storage/backup.tar.gz"

FOLDER is a variable with a list of excluded folders

BUPATH is a variable with a path

Now i want to define a variable EXCLUDE_PATTERN with the pattern for a following tar command (tried 2 variations):

EXCLUDE_PATTERN=`echo $FOLDERS | sed 's/\ /" --exclude="$BUPATH\//g'`
EXCLUDE_PATTERN=`echo $FOLDERS | sed 's/\ /" --exclude="${BUPATH}\//g'`

Then the script runs the tar command:

tar -C \"$BUPATH\" --exclude=\"$BUPATH/$EXCLUDE_PATTERN\" -czf \"$CONFIG_BACKUP\" .

It seems that the variable EXCLUDE_PATTERN is not recognizing the BUPATH variable:

tar -C "/opt/mypath" --exclude="/opt/mypath/folder1" --exclude="${BUPATH}/folder2" --exclude="${BUPATH}/folder3" -czf "/storage/config.tar.gz" .

The expected command should be this:

tar -C "/opt/mypath" --exclude="/opt/mypath/folder1" --exclude="/opt/mypath/folder2" --exclude="/opt/mypath/folder3" -czf "/storage/config.tar.gz" .

I hope someone can help me with this :)

Epyx
  • 35
  • 1
  • 6

2 Answers2

0

FOLDERS='folder1 folder2 folder3'

BUPATH='/opt/mypath'

CONFIG_BACKUP="/storage/backup.tar.gz"

The expected command should be this:

tar -C "/opt/mypath" --exclude="/opt/mypath/folder1" --exclude="/opt/mypath/folder2" --exclude="/opt/mypath/folder3" -czf "/storage/config.tar.gz" .

Well, that's simple. I like the xargs printf to transform a list, ex. prepend something:

# creates a bash array from newline separated output
IFS=$'\n' tarexcludes=($(<<<"$FOLDERS" xargs -n1 printf "--exclude=%s/%s\n" "$BUPATH"))
echo tar -C "/opt/mypath" "${tarexcludes[@]}" -czf "$CONFIG_BACKUP" .

But alternatively you could pick a unique sed command separator and:

tarexcludes=($(<<<"$FOLDERS" tr ' ' '\n' | sed "s~^~--exclude=$BUPATH/~"))

Or use awk:

tarexcludes=($(<<<"$FOLDERS" tr ' ' '\n' | awk -v BUPATH="$BUPATH" '{print "--exclude=" BUPATH "/" $0}')

Notes:

  • Don't use backticks `. They are discouraged and I don't like them. bash obsolete and deprecated syntax
  • The <<<"$FOLDERS" is bash's here string
  • The tr ' ' '\n' substitutes spaces for newline. So it is parsable with sed.
  • The tarexcludes=( ... ) creates a bash array. bashguide arrays
  • You command does not work because echo $FOLDERS will output on a single line, and sed parses lines. So just replace spaces with newlines. Alternatively, use xrandr -n1 or printf "%s" $FOLDERS
  • By convention, upper case variable names are by convention reserved to environmentally exported variables. Use lowercase variable names in your scripts.
Community
  • 1
  • 1
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
0

You can also use a combination of " # instead of ' / as to solve your issue.

EXCLUDE_PATTERN=`echo $FOLDERS |  sed -e "s#\ #\" --exclude=$BUPATH\"/#g"`

but this will output:
folder1" --exclude=/opt/mypath"/folder2" --exclude=/opt/mypath"/folder3

To archive the expected output, it requires this modification:

EXCLUDE_PATTERN=`echo $FOLDERS |  sed -e "s#\(\S\+\)# --exclude=\"$BUPATH/\1\"#g"`

this will output:
--exclude="/opt/mypath/folder1" --exclude="/opt/mypath/folder2" --exclude="/opt/mypath/folder3"

For more information read the StackOverflow post:
Escape a string for a sed replace pattern

Code Rage
  • 555
  • 3
  • 9