简体   繁体   中英

Bash grep array as pattern, thinks it's a file

I'm using Heroku cli to pull a list of backups from Heroku. I'm only looking to grab those that have scheduled backups ( heroku pg:backups:schedules ), but the only way to get their ID is through heroku pg:backups which prints everything. I'm trying to use grep to cut up the output and only give me a list of IDs for ones I need.

My thought is that I should be able to use the array list of backup names I need and grep it against the full list of backups. However, grep either doesn't like the iteration of the array ( array[0] ) or thinks I'm passing it a file name.

for (( x=0; x<DB_COUNT; x++ ))
do
    BACKUP_NAMES[($x)]=$(heroku pg:backups:schedules -a $APP_NAME | sed -n '1!p' | cut -f1 -d":")
    BACKUP_IDS[($x)]=$(heroku pg:backups -a $APP_NAME | grep '[a-z][0-9][0-9][0-9]*' | grep -w $BACKUP_NAMES)
done

I've tried grep -w ${BACKUP_NAMES[$x]} grep -w "$BACKUP_NAMES[$x]" grep -w "$BACKUP_NAMES" and a thousand others but I either get a syntax error or grep thinks $BACKUP_NAMES is a file instead of a pattern. I've been trying to figure this out for hours and I'm just completely stumped.

EDIT:

BACKUP_NAMES contains DATABASE_NAME DATABASE_NAME2

Output of heroku pg:backups

=== Backups
ID    Created at                Status                              Size     Database
a555 2020-01-09 07:26:21 +0000 Completed 2020-01-09 07:30:08 +0000 1.16GB DATABASE_NAME
a554 2020-01-08 07:26:21 +0000 Completed 2020-01-08 07:30:08 +0000 5.93GB DATABASE_NAME2
a553 2020-01-07 07:26:21 +0000 Completed 2020-01-07 07:30:08 +0000 1.16GB DATABASE_NAME3
a552 2020-01-06 07:26:21 +0000 Completed 2020-01-06 07:30:08 +0000 5.89GB DATABASE_NAME4
a551 2020-01-05 07:26:21 +0000 Completed 2020-01-05 07:30:08 +0000 3.21GB DATABASE_NAME5
a550 2020-01-04 07:26:21 +0000 Completed 2020-01-04 07:30:08 +0000 1.16GB DATABASE_NAME6

Output of heroku pg:backups:schedules

=== Backup Schedules
DATABASE_NAME: daily at 5:00 UTC
DATABASE_NAME2: daily at 7:00 UTC

Are you sure you need the loop? I think you can capture the backup names in one variable including the newlines and use that in process substitution as a parameter to grep -w -f :

backup_names=$(heroku pg:backups:schedules -a $APP_NAME | sed -n '1!p' | cut -f1 -d":")
heroku pg:backups -a $APP_NAME | grep -w -f <(echo "$backup_names")

I also removed the grep '[az][0-9][0-9][0-9]*' as it didn't change the output for the data you provided.

Assuming you want to assign an array to the list of backup IDs, how about:

for i in $(heroku pg:backups:schedules -a "$APP_NAME" | sed -n '1!p' | cut -f1 -d":"); do
    backup_ids+=($(heroku pg:backups -a "$APP_NAME" | grep -w "$i" | grep -o '[a-z][0-9][0-9][0-9]*'))
done
echo "${backup_ids[@]}"

Output:

a555 a554

[EDIT]
If your bash does not support += syntax, please try instead:

for i in $(heroku pg:backups:schedules -a "$APP_NAME" | sed -n '1!p' | cut -f1 -d":"); do
    backup_ids[j]=$(heroku pg:backups -a "$APP_NAME" | grep -w "$i" | grep -o '[a-z][0-9][0-9][0-9]*')
    ((j+=1))
done
echo "${backup_ids[@]}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM