'Bash script that changes a JavaScript file based on user input
I want to create a shell command that runs bash commands but also mutates an array in a Javascript file. For example in the file groups.js:
module.exports = {
groups: [
"a",
"b",
"c"
]
}
I want to be able to run a shell command that would wait for user input, for example, +/-, and then will add/remove groups to that groups array in the groups.js file and also run echo "New group added successfully" at the end. Is this possible?
Example of code execution:
./command.sh
What would you like to do? (+ for add, - for remove): +
What group do you want to add: d
New groups:
groups: [
"a",
"b",
"c",
"d"
]
Successfully added "d" to groups.js!
Solution 1:[1]
As mentioned in the comments, it may be a lot easier if people can edit the groups.js file directly, however, if a script must be used, this bash script can be a start.
$ cat command.sh
#!/usr/bin/env bash
file=groups.js
read -rp "What would you like to do? (+ for add, - for remove): " add_or_remove_group
if [[ "$add_or_remove_group" == "+" ]]; then
cat "$file"
read -rp "What group do you want to add: " add_group
clear
sed -i "s/\"[a-z]\"$/&,\n \"$add_group\"/" "$file"
cat "$file"
echo "Successfully added \"$add_group\" to groups.js"
else
cat "$file"
read -rp "What group do you want to remove: " remove_group
clear
tac "$file"| sed "/\[\|{\|}/ ! {/$remove_group/d}" | tac | sed '/,/{N;N;/}/{s/,//}}' | tee "$file"
echo "Successfully removed \"$remove_group\" to groups.js"
fi
$ ./command.sh
What would you like to do? (+ for add, - for remove): +
module.exports = {
groups: [
"a",
"b",
"c"
]
}
What group do you want to add: d
module.exports = {
groups: [
"a",
"b",
"c",
"d"
]
}
Successfully added "d" to groups.js
$ ./command.sh
What would you like to do? (+ for add, - for remove): -
module.exports = {
groups: [
"a",
"b",
"c",
"d"
]
}
What group do you want to remove: a
module.exports = {
groups: [
"b",
"c",
"d"
]
}
Successfully removed "a" to groups.js
Solution 2:[2]
#!/usr/bin/bash
Add_Group() {
eval "$(echo "sed 'H;\$!d;x;/module.exports[^{]*{/,/^}/ s/\n/@@##/g;s/^[^:]*:^[\[]*\[//g;s/\(groups[^\[]*\[\)\([^\\\"]*\)\(.*\\\"\)\([^\]]*\)/\1\2\3,\2\\\"$group\\\"\4/g;s/\(^.*\\\"\)\(.*\)/\n\1\n\2/;h;s/.*\n//;s/^,//g;G;s/\(.*\n\)\(.*\n\)\(.*\)/\2\1/;s/\n//g;s/@@##/\n/g' $File -i")"
}
Remove_Group() {
eval "$(echo "sed '/\\\"$group\\\"/d;H;\$!d;x;s/\n/@@##/g;s/\(^.*\\\"\)\(.*\)/\n\1\n\2/;h;s/.*\n//;s/^,//g;G;s/\(.*\n\)\(.*\n\)\(.*\)/\2\1/;s/\n//g;s/@@##/\n/g' $File -i")"
}
File=groups.js
if [[ "$#" -gt 0 ]]
then
if [[ "$1" == "--add" ]]
then
for group in "${@:2}";
do
Add_Group
done
echo "New Groups:"
cat $File
elif [[ "$1" == "--remove" ]];
then
for group in "${@:2}";
do
Remove_Group
done
echo "New Groups:"
cat $File
fi
else
echo 'What would you like to do? (+ for add, - for remove):'
read function
if [[ "$function" == "+" ]]; then
cat $File
read -p "Enter group names separated by 'space' that you want to add : " input
for group in ${input[@]}
do
Add_Group
done
echo "New Groups:"
cat $File
elif [[ "$function" == "-" ]]; then
cat $File
read -p "Enter group names separated by 'space' that you want to remove : " input
for group in ${input[@]}
do
Remove_Group
done
echo "New Groups:"
cat $File
fi
fi
This script can be used:
Interactively: ./Script.sh
NonInteractively:
./Script.sh --add group1 group2 group3 ..
./Script.sh --remove group1 group2 group3...
Note: Complexity of sed command used is to retain the structure and indents spaces in file without any constraints on regex as in the other answer. Hence if groups.js contains extra texts other than template shown it will work
Short Explanation of sed commands:
Add_Group
Loads the entire file in buffer --> For range /module.exports[^{]*{/,/^}/ ---> Replace \n with @### to restore structure at last ---> Adds comma to last group in existing ---> Adds new group ---> Replace the @@## back to \n
Remove_Group
--->Delete the line containing "group" ---> In case the group removed is the last existing then comma in last group after editing is removed restoring original structure
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
