如何将PortaPuTTY配置文件转换为KiTTY格式并转义特殊字符?
Hey there! Let's work through converting your PortaPuTTY config to KiTTY's format, including that tricky special character encoding requirement. You already have the basic Field=Value → Field\Value\ conversion down with sed, so we'll build on that and add the hex encoding for the specified character ranges.
Background on the Required Encoding
KiTTY expects any character in these ASCII ranges to be encoded as \xHH (lowercase two-digit hex):
- 0x20-0x2F: Space,
! " # $ % & ' ( ) * + , - . / - 0x3A-0x3F:
: ; < = > ? - 0x7B-0x7F:
{ | } ~ DEL
Let's cover three tool-based solutions so you can pick what fits your workflow best:
1. Using awk (Great for Unix-like Systems)
Awk makes it easy to iterate over characters and check their ASCII values. Save this script as putty-to-kitty.awk:
BEGIN { # Define the ASCII ranges we need to encode range1_start = 0x20; range1_end = 0x2F range2_start = 0x3A; range2_end = 0x3F range3_start = 0x7B; range3_end = 0x7F } { # Step 1: Replace "=" with "\" sub(/=/, "\\") # Step 2: Add trailing backslash $0 = $0 "\\" # Step 3: Encode special characters result = "" for (i = 1; i <= length($0); i++) { char = substr($0, i, 1) ascii_val = ord(char) # Check if the character falls in any target range if ((ascii_val >= range1_start && ascii_val <= range1_end) || (ascii_val >= range2_start && ascii_val <= range2_end) || (ascii_val >= range3_start && ascii_val <= range3_end)) { # Append hex-encoded version result = result sprintf("\\x%02x", ascii_val) } else { # Append regular character result = result char } } print result } # Helper function to get ASCII value of a character function ord(c) { return sprintf("%d", c) + 0 }
Run it with:
awk -f putty-to-kitty.awk your_portaputty.conf > kitty_config.conf
2. Using Python (Cross-Platform, Readable)
Python is perfect if you need something that works on Windows, macOS, and Linux alike. Save this as convert_config.py:
import sys # Define the ASCII ranges to encode as hex TARGET_RANGES = [ (0x20, 0x2F), (0x3A, 0x3F), (0x7B, 0x7F) ] def needs_encoding(char: str) -> bool: """Check if a character falls in one of the target ranges.""" ascii_val = ord(char) for start, end in TARGET_RANGES: if start <= ascii_val <= end: return True return False def encode_char(char: str) -> str: """Convert a character to its \xHH hex format.""" return f"\\x{ord(char):02x}" def convert_line(line: str) -> str: """Convert a single PortaPuTTY line to KiTTY format.""" # Remove trailing newline line = line.rstrip("\n") # Replace = with \ line = line.replace("=", "\\") # Add trailing backslash line += "\\" # Encode special characters converted_parts = [] for c in line: if needs_encoding(c): converted_parts.append(encode_char(c)) else: converted_parts.append(c) return "".join(converted_parts) if __name__ == "__main__": # Read from input file (or stdin if no file is passed) input_source = sys.argv[1] if len(sys.argv) > 1 else sys.stdin with open(input_source, "r") if isinstance(input_source, str) else input_source as f: for line in f: print(convert_line(line))
Run it with:
python3 convert_config.py your_portaputty.conf > kitty_config.conf
3. Using sed (Limited, GNU sed Required)
Sed is trickier for dynamic hex encoding because it can't easily get a character's ASCII value. However, if you only need a quick one-liner and have GNU sed, you can chain replacements for each target character. Note: This is less maintainable than the awk/Python options, but works for simple cases:
sed -e 's/=/\\/' \ -e 's/$/\\/' \ -e 's/ /\\x20/g' \ -e 's/!/\\x21/g' \ -e 's/"/\\x22/g' \ -e s/#/\\x23/g \ -e s/$/\\x24/g \ -e s/%/\\x25/g \ -e s/&/\\x26/g \ -e s/'/\\x27/g \ -e s/(/\\x28/g \ -e s/)/\\x29/g \ -e s/*/\\x2a/g \ -e s/+/\\x2b/g \ -e s/,/\\x2c/g \ -e s/-/\\x2d/g \ -e s/./\\x2e/g \ -e s/\//\\x2f/g \ -e s/:/\\x3a/g \ -e s/;/\\x3b/g \ -e s/</\\x3c/g \ -e s/=/\\x3d/g \ -e s/>/\\x3e/g \ -e s/?/\\x3f/g \ -e s/{/\\x7b/g \ -e s/|/\\x7c/g \ -e s/}/\\x7d/g \ -e s/~/\\x7e/g \ your_portaputty.conf > kitty_config.conf
Test Example
If you have a PortaPuTTY line like:SessionName=My Cool Session!
The converted KiTTY line should be:SessionName\My\x20Cool\x20Session\x21\
内容的提问来源于stack exchange,提问作者Todd Blum

