I'm looking to manipulate a shell variable in bash that contains scores from snooker frames. The variable, which I'll refer to as 'score', contains several entries in the format 'player1Score-player2Score(player1Bracket)(player2Bracket)'. I want to extract specific values from this variable without using any external commands like echo or awk.
For example, given a score such as '13-67(63)', I need to derive:
1. Player 1's score
2. Player 2's score
3. First bracket value for Player 1
4. Second bracket value for Player 1
5. First bracket value for Player 2
6. Second bracket value for Player 2
If a value doesn't exist, it should default to -1.
Here are a few examples with expected outputs:
- "13-67(63)" should give: 13, 67, -1, -1, 63, -1
- "120(52,56)-27" should yield: 120, 27, 52, 56, -1, -1
- "80-1" results in: 80, 1, -1, -1, -1, -1
- "59(59)-60(60)" leads to: 59, 60, 59, -1, 60, -1
I'm currently using a mix of commands but it's too slow for processing large datasets. Any advice on how to approach this purely within bash?
2 Answers
I whipped up a quick bash script that might help you out. It's a bit verbose since I'm breaking down each part, but it should do what you need:
```bash
#!/bin/bash
while IFS='-' read -r player1 player2; do
IFS='(' read -r p1_score p1_bracket <<< "${player1}"
IFS=',' read -r p1_bracket_1 p1_bracket_2 <<< "${p1_bracket}"
p1_bracket_1="
${p1_bracket_1/")"/}"
p1_bracket_2="
${p1_bracket_2/")"/}"
IFS='(' read -r p2_score p2_bracket <<< "${player2}"
IFS=',' read -r p2_bracket_1 p2_bracket_2 <<< "${p2_bracket}"
p2_bracket_1="
${p2_bracket_1/")"/}"
p2_bracket_2="
${p2_bracket_2/")"/}"
printf '%d,%d,%d,%d,%d,%dn'
"${p1_score}"
"${p2_score}"
"${p1_bracket_1:--1}"
"${p1_bracket_2:--1}"
"${p2_bracket_1:--1}"
"${p2_bracket_2:--1}"n"
done < scores.txt
```
Your project sounds cool! The approach you're using isn't bad, but you're right that using multiple external commands can be slow when you're dealing with thousands of input lines. Bashing everything together can lead to performance issues since bash is interpreted per line. Have you considered using a single loop structure to read through your data? That way, you can minimize forks and keep it all in-process. That should help speed up the parsing. Keep it simple and focus on using string manipulation inside bash as much as possible!
Thanks for your reply! I see what you mean. My current method feels clunky, so I'll try limiting the external calls and work more on optimizing my loops.
That script is awesome! I plugged it in and ran it against my data. The output matched perfectly with what I had, and it was way faster than my previous method. I’ll definitely use that pattern again!