PHP Guru
PHP Guru

Reputation: 1527

Two Shell Parameter Expansions one after the next doesn't work (Bash)

Using Bash 4.4 I'm trying to get a list of the files from the current directory, put them into an array, and then use shell parameter expansion to remove the files that contain /cache/ and /tmp/ in their paths from the array.

This is what I have so far but it doesn't work. The problem seems to be that the second string replacement happens before the first one stores its result in first_array. So first_array has no value yet when the second replace executes resulting in second_array being blank. The goal is to get a list of files that have a timestamp from yesterday's date that don't contain /cache/ or /tmp/ in their paths.

#!/bin/bash

FIND="$(find . -type f -newermt $(date -d 'yesterday 13:00' '+%Y-%m-%d') ! -newermt $(date '+%Y-%m-%d'))"
readarray -t my_array <<<"$FIND"
first_array="${my_array[@]//*\/tmp\/*/}"
second_array="${first_array[@]//*\/cache\/*/}"

Upvotes: 0

Views: 137

Answers (2)

L&#233;a Gris
L&#233;a Gris

Reputation: 19545

Filtering-out unwanted paths within find, and populating the array with null delimited output from find:

readarray -d '' -t my_array < <(
  find . -type f \
    -not \( \
      -path '*/tmp/*' -o -path '*/cache/*' \
    \) \
    -newermt "$(date -d 'yesterday 13:00' '+%Y-%m-%d %H:%M:%S')" \
    -not -newermt "$(date '+%Y-%m-%d')" \
    -print0
)

Upvotes: 5

chepner
chepner

Reputation: 530950

first_array is not an array; it's a space-separated string. When assigning to second_array, if any of the original array elements had tmp or cache, the entire string is removed.

FIND="$(find . -type f -newermt $(date -d 'yesterday 13:00' '+%Y-%m-%d') ! -newermt $(date '+%Y-%m-%d'))"
readarray -t my_array <<<"$FIND"

# Use array assignment so that each element of my_array becomes a separate
# element of first_array
first_array=("${my_array[@]//*\/tmp\/*/}")

# Ditto for first_array -> second_array
second_array=("${first_array[@]//*\/cache\/*/}")

Upvotes: 3

Related Questions