【问题标题】:sed/find/grep append c# comment to top of file if not there, and replace if existssed/find/grep 如果不存在则将 c# 注释附加到文件顶部,如果存在则替换
【发布时间】:2018-12-30 20:59:49
【问题描述】:

我有一个版权条款,我想将其作为注释附加到目录中一堆文件的顶部 (C#)。它看起来像这样:

/*COPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHT*/
/*C Use, duplication, or disclosure of this software and        T*/
/*C related documentation is blah blah blah blah                T*/
/*C Copyright 2004 - 2018 COMPANY                               T*/
/*C All rights reserved.                                        T*/
/*COPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHT*/

一些文件已经包含一个子句,但是对于 2017 年或 2016 年的日期,我想确保子句中的日期设置为 2018 年。如果没有任何子句,我想插入一个。

到目前为止我已经实现find只修改目录中我需要的文件:

find . -type d \( -name ThirdParty -o -name 3rdParty -o -name 3rd_party \) -prune -o -type f \( -name "*.java" -o -name "*.cs" -o -name "*.cpp" -o -name "*.cxx" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -o -name "*.scala" -o -name "*.css" -o -name "*.js" \) -print0

因为这个子句是每个文件顶部的注释,所以它以/*...*/开始和结束。我尝试使用sed,但这很棘手,因为斜线和星号用于sed 中的其他内容。 这是我的findsed 的组合。这会将 2017 的所有实例替换为 2018 并附加该子句,但即使它已经存在,它也会附加它。如果它不存在,我只需要附加它。

find ....... -print0 | xargs -0 sed -i 's/2004 - 2017/2004 - 2018/g; 1s/^/\/*COPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHT*\/\n\/*C Use, duplication, or disclosure of this software and.....etc'

在 grep 或 sed 中有更好的方法吗?谢谢 编辑:我正在使用 CYGWIN

【问题讨论】:

    标签: sed grep


    【解决方案1】:

    请尝试:

    find ... -print0 | while read -r -d $'\0' f; do
        if [[ $(head -1 "$f") = "/*COPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHT*/" ]]; then
            sed -i 's/2004 - 2017/2004 - 2018/g' "$f"
        else
            sed -i '1s#^#/*COPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHT*/\n/*C Use, duplication, or disclosure of this software and.....etc */\n#' "$f"
        fi
    done
    

    它将find 的结果不传递给xargs,而是传递给while 循环,并根据文件的第一行切换处理。

    【讨论】:

    • 这将在文件中将2004 - 2017 替换为2004 - 2018 任何地方,而不仅仅是在版权注释块中。
    【解决方案2】:

    grep 用于g/re/p,sed 用于s/old/new,因此这两种工具都不适合您的问题。

    这应该可以使用 GNU awk(您在 cygwin 上拥有)进行就地编辑:

    find ... -exec awk -i inplace '
    FNR==1 {
        print "/*COPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHT*/"
        print "/*C Use, duplication, or disclosure of this software and        T*/"
        print "/*C related documentation is blah blah blah blah                T*/"
        print "/*C Copyright 2004 - 2018 COMPANY                               T*/"
        print "/*C All rights reserved.                                        T*/"
        print "/*COPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHT*/"
    
        if ( /COPYRIGHT/ ) { inCopy=1 }
        next
    }
    inCopy && /COPYRIGHT/ { inCopy=0 }
    !inCopy
    ' {} +
    

    如果一个旧的版权块已经存在于文件的开头,它只会用新的块替换整个块。如果您想要更精确地匹配该文本以指示注释块的开始和结束,您可以将每个 /COPYRIGHT/ 更改为 index($0,"/*COPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHTCOPYRIGHT*/")

    【讨论】:

    • 我不得不删除inCopy && /COPYRIGHT/..,因为每次我运行脚本时它都会在块的末尾附加一个关闭版权行,即使它已经有一个。否则工作得很好! inCopy 是什么意思?
    • 该行是必需的,否则当存在现有版权块时您将删除输入的每一行,并且鉴于我发布的代码不可能发生这种情况,您复制时一定做错了/粘贴。 inCopy 只是我创建的一个变量,表示我们在版权块中。
    • 这可能与我的查找操作有关吗?或者我正在使用cygwin?我完全复制并粘贴了
    • 没有。如果您在问题中提供了示例输入和预期输出,那么我们可以测试我们提出的解决方案,但按原样 - idk,我的代码对我来说是正确的。
    • 我确实提供了预期的输出,这是我问题中的第一个代码块。这正是脚本运行后应该出现在文件顶部的内容。至于输入..我提供了我正在编写的脚本的内容。我猜这是唯一的“输入”
    猜你喜欢
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 2016-09-05
    相关资源
    最近更新 更多