How to Convert v2ray Configuration Files to Clash Configuration Files Using Shell Script

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.

v2ray configuration

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 <
v2ray configuration

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.

Reference: Comparison of Regular Expression Engines/Flavors