Today, I originally planned to write a shell script to convert v2ray configuration files to clash configuration files. Since the key parameters of both are consistent, only the format is different. The first thing that came to my mind was to use template strings to parse variables.

The image above shows the original format of the v2ray client, and the one below is the format required by the clash client.
My code implementation is as follows:
#!/bin/bash trojanArray=(Type Password Domain Port Name) template=' - {"type":${Type},"name":${Name},"server":${Domain},"password":${Password},"port":${Port},"udp":true,"skip-cert-verify":true}' regex="(.*?)://(.*?)@(.*?):([0-9]+)#(.*)" echo -e \ " trojan://[email protected]:443#HK1 trojan://[email protected]:443#HK3 trojan://[email protected]:443#HK0 trojan://[email protected]:443#JP1 " | while read line; do if [[ $line =~ $regex ]]; then for i in ${!trojanArray[@]}; do eval "${trojanArray[$i]}=${BASH_REMATCH[$i+1]}" done eval "cat <

My thought process is roughly as follows:
- Put the variable names into an array as literals, and then dynamically assign values through eval.
- Use the built-in bash regex variable BASH_REMATCH to get the matched keywords.
- Assign values to the template string through eval $template.
Then I asked Xuejin for his thoughts, and I was blown away.

One line of his code equals dozens of mine. A true expert is indeed unmatched. Xuejin is the best!
Here are some issues I encountered during use:
The built-in bash regex does not support the [\d]+ syntax by default. Here is an example using grep.

- -E, –extended-regexp PATTERN is an extended regular expression (abbreviated as ERE)
- -G, –basic-regexp PATTERN is interpreted as a basic regular expression (BRE), which is the default setting
- -F, –fixed-strings PATTERN is a set of newline-separated strings
- -P, –perl-regexp PATTERN is a Perl regular expression
So the default regex is not supported, but using Perl regex can support it.