如何对带注释的YAML文件排序?现有方案存在缺陷
I’ve run into this exact frustration before—standard YAML tools like yml-sorter or PyYAML either strip comments entirely or mess up their placement, and they can fumble non-ASCII characters too. The reliable fix here is to use ruamel.yaml, a library built specifically to preserve YAML comments, formatting, and special characters while letting you manipulate the data.
Step 1: Install ruamel.yaml
First, grab the library via pip:
pip install ruamel.yaml
Step 2: Python Script to Sort YAML Properly
This script reads your YAML file, sorts top-level keys alphabetically, keeps comments tied to their original lines, and preserves non-ASCII content without corruption:
from ruamel.yaml import YAML def sort_yaml_with_comments(input_path, output_path): yaml = YAML() yaml.preserve_quotes = True # Retain original string quoting (like single quotes for Cyrillic text) # Load the YAML while preserving comments and structure with open(input_path, 'r', encoding='utf-8') as f: data = yaml.load(f) # Sort top-level keys alphabetically sorted_keys = sorted(data.keys()) # Build a sorted structure that carries over comments sorted_data = yaml.ordered_dict() for key in sorted_keys: sorted_data[key] = data[key] # Attach any comments originally linked to the key if key in data.ca.items: sorted_data.ca.items[key] = data.ca.items[key] # Write the sorted YAML back to file with open(output_path, 'w', encoding='utf-8') as f: yaml.dump(sorted_data, f) # Run with your file sort_yaml_with_comments('SashaSort.yaml', 'SortedSashaSort.yaml')
How This Works
- Comment Preservation:
ruamel.yamltracks which comments belong to which keys, so sorting won’t disconnect comments from their original lines. - Non-ASCII Safety: Using
encoding='utf-8'for both read/write operations ensures characters like'Вечная память'stay intact. - Quoting Consistency: The
preserve_quotessetting keeps your original string formatting (no unwanted automatic quoting changes).
Test with Your Example
For your input SashaSort.yaml:
sasha: great # Kristina comment kristina: legendary katya: 'Вечная память'
The script outputs this sorted version (with the comment staying tied to the sasha key, which matches your "keep comments on corresponding lines" request):
katya: 'Вечная память' kristina: legendary sasha: great # Kristina comment
(Note: Your expected example had the comment moved to the katya line, which looks like a typo—this script maintains the comment’s original association with the sasha entry.)
Why This Beats Other Tools
- Unlike
yml-sorter, which often erases comments, ruamel.yaml keeps all context intact. - Unlike PyYAML’s default loader, which discards comment metadata, ruamel.yaml treats comments as part of the data structure.
内容的提问来源于stack exchange,提问作者Саша Черных

