【问题标题】:Replace Words in the parentheses to put into quotations替换括号中的单词以放入引号中
【发布时间】:2023-03-30 14:21:01
【问题描述】:

我想替换括号中的单词以放入引号中。 我的previous question 在括号中有一个值。这个问题和我之前的问题一样,但是想到了一个场景,我将在括号中包含多个值。

以下是我在其中一个可变数据中的数据-

SELECT          * 
FROM            ( 
                       SELECT table1 file2.txt file.txt queues qdefinitions parameters trap-deposit-dstran.dat.2016-08-07 
                       FROM   cs_case 
                       WHERE  ant_cd='FI_BASE_TENANT') t1 
LEFT OUTER JOIN table2 t2 
ON              t2.case_id=t1.case_id 
LEFT OUTER JOIN table3 t3 
ON              t3.service_xid=t1.service_xid 
LEFT OUTER JOIN table4 t4 
ON              t4.service_id=t1.service_id 
WHERE           ( 
                                t1.casestatus_cd = (new,retired,pending,OPEN,closed) 
                OR              t1.case_status_num = (1,2,3,4) ) 
GROUP BY        t1.case_reference, 
                t2.last_scrfp, 
                t1.service_id 
ORDER BY        t2.last_scrfp DESC

这就是我想要的。

SELECT          * 
FROM            ( 
                       SELECT table1 file2.txt file.txt queues qdefinitions parameters trap-deposit-dstran.dat.2016-08-07 
                       FROM   cs_case 
                       WHERE  ant_cd='FI_BASE_TENANT') t1 
LEFT OUTER JOIN table2 t2 
ON              t2.case_id=t1.case_id 
LEFT OUTER JOIN table3 t3 
ON              t3.service_xid=t1.service_xid 
LEFT OUTER JOIN table4 t4 
ON              t4.service_id=t1.service_id 
WHERE           ( 
                                t1.casestatus_cd = ('NEW','RETIRED','PENDING','OPEN','CLOSED') 
                or              t1.case_status_num = (1,2,3,4) ) 
GROUP BY        t1.case_reference, 
                t2.last_scrfp, 
                t1.service_id 
ORDER BY        t2.last_scrfp DESC

之前我使用过如下的 sed 命令

sed -E 's/\(([^(,$1)'\'']+)\)/('\''\1'\'')/g' Filename.txt

【问题讨论】:

  • 嗨尼克,如前所述,您应该在问题中使用markup 以使事情更清楚。上次我为您设置了格式,但我认为您至少应该了解是否要发布多个问题。
  • 您应该解释为什么这个问题与您的last one 不同。在我看到 Ed Morton's comment 建议你提出一个新问题之前,我打算投票结束。
  • 我的上一个问题在括号中有一个值。 Ed Morton 评论了一个我稍作修改的命令。这与我之前的问题相同,但想到了一个场景,我将在括号中包含多个值。我正在尝试在 SAS 中自动化该过程,我将在其中运行 unix 命令以使用 sed 命令替换查询。希望这是有道理的。
  • @Nick 请edit 将该信息放入您的问题中。
  • 您正在修改的这段文字的来源是什么?为什么文本需要插入引号?这是一次性的事情还是你有很多这些无效的文本文件?此外,您的示例 SQL 无效,因为您不能使用 = 测试值是否在列表中,需要使用 IN 运算符。 t1.case_status_num IN (1,2,3,4)

标签: linux perl awk sed sas


【解决方案1】:

这不再是对单个行的简单替换,因此它不再是 sed 的工作,而是 awk 的工作:

$ cat tst.awk
BEGIN { RS="^$"; ORS="" }
{
    while ( match($0,/(=\s*\()([^()]+)(\))/,a) ) {
        if ( a[2] ~ /[^0-9,]/) {
            gsub(/,/,"\047,\047",a[2])
            a[2] = "\047" toupper(a[2]) "\047"
        }
        print substr($0,1,RSTART-1) a[1] a[2] a[3]
        $0 = substr($0,RSTART+RLENGTH)
    }
    print
}

$ awk -f tst.awk file
SELECT          *
FROM            (
                       SELECT table1 file2.txt file.txt queues qdefinitions parameters
trap-deposit-dstran.dat.2016-08-07
                       FROM   cs_case
                       WHERE  ant_cd='FI_BASE_TENANT') t1
LEFT OUTER JOIN table2 t2
ON              t2.case_id=t1.case_id
LEFT OUTER JOIN table3 t3
ON              t3.service_xid=t1.service_xid
LEFT OUTER JOIN table4 t4
ON              t4.service_id=t1.service_id
WHERE           (
                                t1.casestatus_cd = ('NEW','RETIRED','PENDING','OPEN','CLOSED')
                OR              t1.case_status_num = (1,2,3,4) )
GROUP BY        t1.case_reference,
                t2.last_scrfp,
                t1.service_id
ORDER BY        t2.last_scrfp DESC

上面使用 GNU awk 作为第三个参数来 match() 和多字符 RS。

【讨论】:

    【解决方案2】:

    为什么会出现如此疯狂的复杂情况?

    怎么样:

    $line =~ s/(([^(]+))/"\1"/g;

    注意 () 组合了一个子表达式; ( 匹配文字 '(' (无需省略 ')'); [^(]+ 匹配断言括号内的一组非括号; "\1" 引用匹配的内容,即。 , 括号内发生了什么,括号本身除外。

    【讨论】:

    • 你测试过这个吗?这不起作用。此外,perl 更喜欢$1 而不是\1(避免\1 better written as $1 的警告)。
    • 是的,\1 旨在用于正则表达式;你在替换文本中使用$1
    【解决方案3】:

    使用sln 提供的solution 使用Regex Quote-Like operators,以提供可读性/可维护性。

    加上mob 提供的另一个solution 用于优雅的引用机制。

    加上一些编码,为您的特定场景将所有内容组合在一起:

    use strict;
    use warnings 'all';
    
    # create a regex quote-like string for our match
    my $rx = qr{\(([^)]+)\)};
    
    # step through STDIN
    while(<>) {
    
        # Replace matching (...) sections by passing the matched part
        # to QuoteText() and subsituting the result it returns.
        #
        # Note the 'e' and 'g' flags to s///, e enables "extended"
        # operations which allows us to call QuoteText() and g 
        # replaces _all_ occurances on a line
        s/$rx/QuoteText($1)/eg;
    
        # print out the line (post any possible substitutions)
        print;
    }
    
    sub QuoteText {
        my $text = shift;
    
        # the variable we will use to return our result
        my $result;
    
        # Does the text contain commas and also contains alphabetical characters?   
        if($text =~ /,/ && $text =~ /[a-z]/i) {
    
            # split up the text around commas, then rejoin them with the 
            # string ',', and then prepend and append a single quote 
            # at the begining and end of line. So one,two becomes 'one','two'
            $result = q/'/ . join(q/','/, split (',', $text)) . q/'/;
    
        # The word _only_ contains numbers, spaces and commas, leave as is
        } elsif($text =~ /^[\s\d,]+$/i) {
            $result = $text;
    
        # We possibly have just a single word? default to quoting the word
        } else {
            $result = qq/'$text'/;
        }
    
        # return our result wrapped in ()'s
        return "($result)";
    }
    

    注意:我没有将引用的单词大写。如果你想实现这一点,你需要mapuc split 的部分。同样在要引用的单词是数字和单词的混合的情况下,它最终会引用所有的数字和单词。如果这是一个问题,那么最好通过拆分单词、循环遍历每个单词、评估其内容以查看它是否需要引用,然后将结果连接到返回的字符串来更好地解决此问题。

    【讨论】:

      猜你喜欢
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 2020-10-24
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      相关资源
      最近更新 更多