sed多模式单行输出问题:如何将语言与属地格式化输出为指定形式
解决sed处理language-territory格式的问题
你的问题出在原sed命令的正则逻辑上——你试图用|同时匹配language和territory,但正则分支的优先级和捕获组的使用方式不对,导致无法正确配对语言和属地。咱们一步步来修正:
先分析原命令的问题
你写的命令:
sed -nE 's/^language|territory\s+"(.+)"$/\1 \2/p'
这里的|把正则分成了两个独立分支:
^language:只匹配行开头的language,没有任何捕获组,所以\1和\2都是空值territory\s+"(.+)"$:只匹配行末尾的territory和引号内容,只有一个捕获组\1,\2依然是空
这就导致替换出来的内容完全不符合预期,根本没法把语言和属地对应起来。
正确的处理方案
根据你的需求,我们需要把每一组language "X" territory "Y"转换成X (Y),然后去重、合并成一行。分两种情况处理:
情况1:原文件每行一组language-territory
如果你的languages.txt是每行一条记录,比如:
language "Afar" territory "Djibouti"
language "Afar" territory "Eritrea"
language "Afar" territory "Eritrea"
language "Afar" territory "Ethiopia"
用这条命令:
sed -E 's/language "([^"]+)" territory "([^"]+)"/\1 (\2)/' languages.txt | sort -u | tr '\n' ' '
各部分作用:
sed部分:匹配整行的language "X" territory "Y",用捕获组\1提取语言名,\2提取属地,替换成X (Y)sort -u:去除重复的条目(比如你例子里重复的Afar (Eritrea))tr '\n' ' ':把每行的结果转换成空格分隔的单行
情况2:原文件是一整行连续的内容
如果你的languages.txt是一整行的连续文本,比如:
language "Afar" territory "Djibouti" language "Afar" territory "Eritrea" language "Afar" territory "Eritrea" language "Afar" territory "Ethiopia"
用这条命令:
sed -E 's/language "([^"]+)" territory "([^"]+)"/\1 (\2) /g' languages.txt | sed 's/ $//' | tr -s ' '
各部分作用:
- 第一个
sed:全局替换每一组language...territory为X (Y)(加空格分隔) - 第二个
sed:去掉末尾多余的空格 tr -s ' ':压缩可能出现的连续空格,保证格式整洁
测试结果
不管哪种情况,最终都会输出你想要的格式:
Afar (Djibouti) Afar (Eritrea) Afar (Ethiopia)
内容的提问来源于stack exchange,提问作者Marcelo
相关产品推荐
相关产品推荐

