【问题标题】:In GNU Make, how do I convert a variable to lower case?在 GNU Make 中,如何将变量转换为小写?
【发布时间】:2010-10-14 10:57:53
【问题描述】:

这是一个愚蠢的问题,但是.... 使用 GNU Make:

VAR = MixedCaseText
LOWER_VAR = $(VAR,lc)

default:
        @echo $(VAR)
        @echo $(LOWER_VAR)

在上面的例子中,将 VAR 的内容转换为小写的正确语法是什么?显示的语法(以及我遇到的所有其他内容)导致 LOWER_VAR 为空字符串。

【问题讨论】:

    标签: makefile


    【解决方案1】:

    你总是可以生成 tr

    LOWER_VAR = `echo $(VAR) | tr A-Z a-z`
    

    LOWER_VAR  = $(shell echo $(VAR) | tr A-Z a-z)
    

    您尝试调用的“lc”函数来自GNU Make Standard Library

    假设已安装,正确的语法应该是

    LOWER_VAR  = $(call lc,$(VAR))
    

    【讨论】:

    • 在我的例子中,$(call lc,$VAR) 语法也会导致一个空字符串。我猜这个库没有安装,要求我们所有的开发人员都安装它对我来说不是最佳选择。但是,产卵正在发挥作用。
    • 可选地,在其周围放置一个 $(strip) 以消除末尾的换行符:$(strip ($shell echo $(VAR) | tr A-Z a-z))
    【解决方案2】:

    您可以直接在 gmake 中执行此操作,而无需使用 GNU Make 标准库:

    lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
    
    VAR = MixedCaseText
    LOWER_VAR = $(call lc,$(VAR))
    
    all:
            @echo $(VAR)
            @echo $(LOWER_VAR)
    

    它看起来有点笨拙,但它可以完成工作。

    如果您使用 $(shell) 品种,请务必使用 := 而不是仅使用 =,如 LOWER_VAR := $(shell echo $VAR | tr A-Z a-z)。这样,您只需在声明变量时调用一次 shell,而不是每次引用变量时!

    希望对您有所帮助。

    【讨论】:

    • 我见过的唯一一个不管操作系统和 shell 工具都可以工作的解决方案。
    • @mtalexan 但它不起作用; A-Z 仅涵盖您可能想要转换为小写的一小部分字符。 É.h、Проблемы.c 等等等等。
    • @James Moore,你是对的,但另一个答案中给出的 tr 语法也不能保证在非 bash shell 上得到支持。从技术上讲,上面给出的语法将支持所有 ASCII 字符,并且可以根据需要扩展为 Unicode 字符,因为它是映射转换
    • “分而治之”应用的一个很好的例子:)
    【解决方案3】:

    处理带重音的大写字母:

    LOWER_VAR  = $(shell echo $VAR | tr '[:upper:]' '[:lower:]')
    

    结果:

    $ VAR="Éclipse"
    $ echo $VAR | tr A-Z a-z
    Éclipse
    $ echo $VAR | tr '[:upper:]' '[:lower:]'
    éclipse
    

    【讨论】:

    • 要删除所有空格,请尝试LOWER_VAR = $(shell $VAR | tr '[:upper:]' '[:lower:]' | sed 's/ //g')
    • 我相信你的意思是“LOWER_VAR = $(shell echo $(VAR) | tr '[:upper:]' '[:lower:]')”。没有回声,这真的没有意义。
    • 是的 - 另一种实现这项工作的方法是将$VAR 替换为$1,因此用法将是$(call LOWER_VAR,value or $V or $(VARIABLE))。通常,我单引号引用我的 echo 语句:echo '$1' 并非万无一失,但它减少了重定向、shell 扩展等的机会。
    【解决方案4】:

    我觉得这个更干净一些...

    $(shell tr '[:upper:]' '[:lower:]' <<< $(VAR))
    

    【讨论】:

    • 那需要shell支持
    【解决方案5】:

    如果安装了 Python,它甚至可以在 Windows 上运行:

    $(shell python -c "print('$(VAR)'.lower())")
    

    【讨论】:

      【解决方案6】:

      GNU make 不包括用于大小写转换的字符串函数。因此,默认情况下没有定义lc 函数。

      但 GNU Make 通常会启用 GNU Guile 支持(例如 Fedora 33 就是这种情况)。

      因此,您可以只调用 Guile 函数来转换大小写:

      VAR = MixedCaseText
      LOWER_VAR = $(guile (string-downcase "$(VAR)"))
      
      default:
              @echo $(VAR)
              @echo $(LOWER_VAR)
      

      或者如果你想封装 Guile 调用:

      VAR = MixedCaseText
      LOWER_VAR = $(call to_lower,$(VAR))
      
      
      define to_lower
      $(guile (string-downcase "$(1)"))
      endef
      
      
      default:
              @echo $(VAR)
              @echo $(LOWER_VAR)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-11
        • 1970-01-01
        相关资源
        最近更新 更多