I'm trying to cleanup inactive channels from a list of json objects in a channels.json file from Slack. I got the list of inactive channels (defined as not updated in last 90 days) by checking the timestamp of the last message in the channel directory in my export and writing the list of inactive channels to an array as this data is not available in the json objects themselves. Only problem is I don't know how to arrange it so that each of the channels in my array are removed from the input before writing to a new output file. See the missing something important here
comment in my function code below.
Here's my current function.
exclude-inactive-channels () {
# Check for a valid argument
if [ -z $1 ]; then
echo "No arguments supplied."
return 1
elif [ $# -gt 1 ]; then
echo "Too many arguments supplied."
return 1
elif [ ! -f $1 ]; then
echo "File doesn't exist."
return 1
fi
cutoff_epoch=$(gdate -d "90 days ago" '%s')
inactive_channels=()
for channel in $(jq -r '.[] | select(.is_archived == false) | .name' $1); do
if [[ -d $channel ]]; then
last_post=$(ls -1 $channel |sort -n |tail -1 |awk -F'.' '{print $1}')
last_post_epoch=$(gdate -d "$last_post" '%s')
if [[ $last_post_epoch -lt $cutoff_epoch ]]; then
inactive_channels =("$channel")
echo -n "Removing $channel directory. Last post is $last_post."
#rm -rf $channel
echo -e "\033[0;32m[OK]\033[0m"
fi
fi
done
echo "Removing inactive channels from $1 and writing output to new-$1."
for inactive_channel in ${inactive_channels[@]}; do
# Next line is untested pseudo code
jq -r '.[] | del(.name == $inactive_channel)' $1 #missing something important here
done | jq -s > new-${1}
echo "Replacing $1 with new-$1."
# mv new-${1} $1
}
Calling this function:
exclude-inactive-channels channels.json
Example Input:
[
{
"id": "",
"name": "announcements",
"created": 1500000000,
"creator": "",
"is_archived": false,
"is_general": true,
"members": [
"",
],
"pins": [
{
"id": "",
"type": "C",
"created": 1500000000,
"user": "",
"owner": ""
},
],
"topic": {
"value": "",
"creator": "",
"last_set": 0
},
"purpose": {
"value": "company wide announcements",
"creator": "",
"last_set": 1500000000
}
},
{
"id": "",
"name": "general",
"created": 1500000000,
"creator": "",
"is_archived": false,
"is_general": true,
"members": [
"",
],
"pins": [
{
"id": "",
"type": "C",
"created": 1500000000,
"user": "",
"owner": ""
},
],
"topic": {
"value": "",
"creator": "",
"last_set": 0
},
"purpose": {
"value": "general",
"creator": "",
"last_set": 1500000000
}
},
]
CodePudding user response:
More efficient is to feed jq all your channels to delete at once, rather than one-at-a-time.
# you need to comment one of these out for out.json to not be an empty list
inactive_channels=(
"announcements"
"general"
)
jq --rawfile inactive_channel_stream <(printf '%s\0' "${inactive_channels[@]}") '
# generate an object mapping keys to delete to a truthy value
INDEX($inactive_channel_stream | split("\u0000")[]; .) as $inactive_channels
| map(select(($inactive_channels[.name] // false) | not))
' <in.json >out.json