You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从queueN.txt中提取每行首尾括号内的字符串?

提取文本中每行首尾括号内的内容

问题描述

现有queueN.txt文件,内容如下:

uid=524357(aali95) gid=524357(aali95) groups=524357(aali95),611684(com_perkinsd),695433(bios420)
uid=524534(aalman4) gid=524534(aalman4) groups=524534(aalman4),426634(chem_shared)
uid=748146(abaner29) gid=748146(abaner29) groups=748146(abaner29)
uid=583567(abench2) gid=583567(abench2) groups=583567(abench2),875029(cs494_paka)
uid=570875(abhima4) gid=570875(abhima4) groups=570875(abhima4),875029(cs494_paka)
uid=603522(abokifa) gid=603522(abokifa) groups=603522(abokifa),750403(cme_abokifa),831682(vasphpc)
uid=747491(aboyap2) gid=747491(aboyap2) groups=747491(aboyap2),10(wheel),516955(acr_admin)
uid=500092(adavar2) gid=500092(adavar2) groups=500092(adavar2),10513(domain_users),426636(cme_shared),605853(cme_sarakad),831682(vasphpc)
uid=543988(adench2) gid=543988(adench2) groups=543988(adench2),545740(phys_hyowon)
uid=738525(aditya06) gid=738525(aditya06) groups=738525(aditya06),705095(acr_workshop)\

需要提取每行中第一组括号内的字符串和最后一组括号内的字符串,输出格式如下:

aali95 bios420
aalman4 chem_shared
abaner29 abaner29
abench2 cs494_paka
abhima4 cs494_paka
abokifa vasphpc
aboyap2 acr_admin
adavar2 vasphpc
adench2 phys_hyowon
aditya06 acr_workshop

你尝试的脚本存在逻辑错误:for f in \cat queueN.txt`; do cat ${f} | sed 's...'; done > queue.txt 会把文件内容按空格拆分成单个单词赋值给f,而非逐行处理,且cat ${f}`会尝试读取以单词命名的文件,完全不符合需求。

解决方案

方法1:使用sed一行完成

利用sed的正则匹配,直接捕获并替换目标内容,兼容单行单括号的情况:

sed -E 's/.*\(([^)]+)\)(.*\(([^)]+)\))?$/\1 \3/' queueN.txt | sed 's/ $//' > queue.txt
  • 解释:
    • .*\(([^)]+)\):匹配任意字符直到第一个(,捕获括号内的非)字符(第一个目标内容)
    • (.*\(([^)]+)\))?$:匹配剩余内容直到最后一个(,捕获括号内的内容(最后一个目标内容),?$表示这部分可选(兼容单行单括号的情况)
    • 第二个sed 's/ $//':处理单行单括号的行,去掉末尾多余的空格

方法2:使用awk处理(更直观)

awk逐行提取所有括号内的内容,再输出首尾两项:

awk '{
    count = 0
    while (match($0, /\(([^)]+)\)/, arr)) {
        content[++count] = arr[1]
        $0 = substr($0, RSTART + RLENGTH)
    }
    print content[1], content[count]
}' queueN.txt > queue.txt
  • 解释:
    • 用match函数循环匹配每行中的括号内容,存入数组content
    • 最后输出数组的第一个元素和最后一个元素

方法3:改进循环(符合你最初的思路)

如果一定要用循环逐行处理,用while read替代for避免拆分单词:

while IFS= read -r line; do
    first=$(echo "$line" | sed -E 's/.*\(([^)]+)\).*/\1/')
    last=$(echo "$line" | sed -E 's/.*\(([^)]+)\)$/\1/')
    echo "$first $last"
done < queueN.txt > queue.txt
  • while IFS= read -r line:逐行读取文件内容,保留空格和特殊字符
  • 分别用sed提取第一个和最后一个括号内的内容,再拼接输出

内容的提问来源于stack exchange,提问作者anikaM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:53:19