如何在 shell 脚本中的一行中提取两个或多个子字符串

How do I abstrct two or more substring in one single line In shell script

我需要编写一个shell脚本来将字符串替换为TS文件中的序列号,而这些字符串包含在一个函数中,实际上它们是函数的第一个参数,因此我尝试了查找由该函数名组成的所有子字符串,我的问题是,一行中可能调用了两个或多个函数,我使用 cat 命令读取 TS 文件 然后我试了

localize=`cat MailDetailLayer.ts | grep -o GetLocalize\(*` 
for i in $localize
do
echo $i
done

但只有 returns 每个“GetLocalize(”对我来说,然后我尝试了

localize=cat MailDetailLayer.ts 
for i in $localize
do
echo $i
    if [[ $i == *"GetLocalize(\""* ]];then
        echo $i
        delper=${i#*\"}
        
        delbehand=${delper%%\"*}
        echo $delbehand
        let flag++
        echo $flag
    fi

done

但它会跳过不正确的空格。 我需要抽象每个字符串,例如:GetLocalize("ahfjkhfak", xx, yy)

中的“ahfjkhfak”

我的 TS 文件是这样的:

class MailDetailLayer extends BaseLayerScript<VMMailDetail> {
    protected static _resPath = "mail/com_read"

    protected _mailInfo : IEmailInfo

    constructor(layer: ILayer, initData: {mailInfo : IEmailInfo}) {
        super(layer, initData)
        this._mailInfo = initData.mailInfo
    }

    protected provideVMData(vm: VMMailDetail) {
        return {
            context : this.formMailContext(),
            attachment : this._mailInfo.attachment 
        }
    }GetLocalize("this is a string")


    async onDelete(){
        let confirmDel = await Game.Common.showMessage(GetLocalize("replace this string to number"), GetLocalize("rasdbhjbvx"), GetLocalize("there might be many GetLocalize functions in one line"))
        if(confirmDel == 1){
            let ret = await Game.Email.delMail(EEmailType.Defult, this._mailInfo.eid) 
            if(ret){
                Game.Email.Data.delMail(this._mailInfo.eid)
                this.Layer.CloseSelf()
            }
        }
    }


    GetLocalize("and this function has other parameters", sfajh, asjhfbhk)
    async onReceiveAttachment(){
        let ret = await Game.Email.receiveAttachment(EEmailType.Defult, this._mailInfo.eid)
        if(ret){
            Game.Email.Data.receiveAttachment(this._mailInfo.eid)
        }
    }

    formMailContext(){
        if(this._mailInfo.eContext){
            return this._mailInfo.eContext
        }
        let context =  GetLocalize(ConfigEntry.Mail.getRowById(this._mailInfo.tid).TextContent)
        GetLocalize("if the first parameter is not a string nothing happens")
        // TODO

        // if(this._mailInfo.specialValueArr){
        //     return GetLocalize(context, ...this._mailInfo.specialValueArr)
        // }
        return  context
    }
}

在 shell 中执行 search-and-replace 不是正确的工具:首先没有“全局”选项。我建议使用更强大的文本处理语言,如 perl 或 python.

例如

perl -pe '
    s{(?<=GetLocalize\(")(.*?)(?=")}
    {
        # your transformation goes here, for example
        reverse uc 
    }ge
' file.ts

产出

class MailDetailLayer extends BaseLayerScript<VMMailDetail> {
    protected static _resPath = "mail/com_read"

    protected _mailInfo : IEmailInfo

    constructor(layer: ILayer, initData: {mailInfo : IEmailInfo}) {
        super(layer, initData)
        this._mailInfo = initData.mailInfo
    }

    protected provideVMData(vm: VMMailDetail) {
        return {
            context : this.formMailContext(),
            attachment : this._mailInfo.attachment
        }
    }GetLocalize("GNIRTS A SI SIHT")


    async onDelete(){
        let confirmDel = await Game.Common.showMessage(GetLocalize("REBMUN OT GNIRTS SIHT ECALPER"), GetLocalize("XVBJHBDSAR"), GetLocalize("ENIL ENO NI SNOITCNUF EZILACOLTEG YNAM EB THGIM EREHT"))
        if(confirmDel == 1){
            let ret = await Game.Email.delMail(EEmailType.Defult, this._mailInfo.eid)
            if(ret){
                Game.Email.Data.delMail(this._mailInfo.eid)
                this.Layer.CloseSelf()
            }
        }
    }


    GetLocalize("SRETEMARAP REHTO SAH NOITCNUF SIHT DNA", sfajh, asjhfbhk)
    async onReceiveAttachment(){
        let ret = await Game.Email.receiveAttachment(EEmailType.Defult, this._mailInfo.eid)
        if(ret){
            Game.Email.Data.receiveAttachment(this._mailInfo.eid)
        }
    }

    formMailContext(){
        if(this._mailInfo.eContext){
            return this._mailInfo.eContext
        }
        let context =  GetLocalize(ConfigEntry.Mail.getRowById(this._mailInfo.tid).TextContent)
        GetLocalize("SNEPPAH GNIHTON GNIRTS A TON SI RETEMARAP TSRIF EHT FI")
        // TODO

        // if(this._mailInfo.specialValueArr){
        //     return GetLocalize(context, ...this._mailInfo.specialValueArr)
        // }
        return  context
    }
}

与任何试图解析代码的 regex-based 解决方案一样,这很容易被阻止,例如:

GetLocalize("this string \"contains embedded quotes\" which is a problem")

将导致

GetLocalize("\ GNIRTS SIHT"contains embedded quotes\" which is a problem")