【问题标题】:Surround every line with single quote except empty lines除空行外,用单引号将每一行括起来
【发布时间】:2019-09-11 18:11:37
【问题描述】:

我的目标是在文件中的每一行添加一个撇号并跳过空行。

file.txt

Quote1
Quote2

Quote3

到目前为止,我使用过 sed:

sed -e "s/\(.*\)/'\1'/"

它的作用是在空行中创建撇号:

'Quote1'
'Quote2'
''
'Quote3'

我的目标:

'Quote1'
'Quote2'

'Quote3'

我怎样才能通过使用 sed 来实现这一点,或者它应该是 awk。

【问题讨论】:

    标签: unix awk sed text-processing


    【解决方案1】:

    .* 表示zero or more characters,你想要1 or more characters,在任何sed 中都是..*

    $ sed "s/..*/'&'/" file
    'Quote1'
    'Quote2'
    
    'Quote3'
    

    您还可以将该正则表达式写为 GNU sed 中的 .\+、POSIX sed 中的 .\{1,\} 和 GNU 或 OSX/BSD sed 中的 .+,当使用 -E 调用时。

    以上假设所有空格的行都应该被引用。如果那是错误的,那么:

    $ sed "s/.*[^[:blank:]].*/'&'/" file
    'Quote1'
    'Quote2'
    
    'Quote3'
    

    在任何 awk 中假设所有空格的行都应该被引用:

    $ awk '/./{$0="\047" $0 "\047"}1' file
    'Quote1'
    'Quote2'
    
    'Quote3'
    

    否则:

    $ awk 'NF{$0="\047" $0 "\047"}1' file
    'Quote1'
    'Quote2'
    
    'Quote3'
    

    你可以看到上面的区别:

    $ printf '   \n' | sed "s/..*/'&'/"
    '   '
    $ printf '   \n' | sed "s/.*[^[:blank:]].*/'&'/"
    
    $ printf '   \n' | awk '/./{$0="\047" $0 "\047"}1'
    '   '
    $ printf '   \n' | awk 'NF{$0="\047" $0 "\047"}1'
    
    $
    

    【讨论】:

    • 我很想写sed "/[^[:blank:]]/s/.*/'&'/"——我觉得更整洁一些。
    • @glennjackman idk,我只是将 sed 用于s/old/new/,任何比我使用 awk 更高级的东西。
    【解决方案2】:

    一种方式:

    awk '$1{$0 = q $0 q}1' q="'" file
    

    仅当第一列 ($1) 具有一定价值时才添加引号。 1 打印每一行。

    【讨论】:

    • 将值分配给 arg 列表中的变量会使 ARGV 变得混乱,并使这些变量在 BEGIN 部​​分中不可用,如果/当您以后需要时,可能会咬到您。 唯一的时间是当您需要在列出的文件之间为变量分配不同的值时,例如awk '...' FS=':' file1 FS='@' file2。使用-v var=val 分配变量,除非您需要不扩展转义序列然后使用ENVIRON[] 或仅将值存储在ARGV[] 中。请参阅cfajohnson.com/shell/cus-faq-2.html#Q24 处的示例 a、d 和 f
    • 哦,$1{...} 不会转义任何以0 开头的行。测试空行的方法是NF{...}/./{...},具体取决于您的 FS 值以及一行空白字符是否被视为空行。
    【解决方案3】:

    假设您想将单引号添加到只包含空格的行中:

    sed -E "/./s/(.*)/'\1'/"
    

    【讨论】:

    • 也许是sed "/./s/.*/'&'/" file?
    【解决方案4】:

    另一个sed

    sed '/^$/!{s/^/\x27/;s/$/\x27/}' file
    

    上面的脚本说

    • 寻找空行 - /^$/ - 模式。
    • 对于不遵循上述模式的行 (!),请将 start(^) 和 end($) 替换为单引号 (\x27)。

    【讨论】:

      【解决方案5】:

      您可以使用perl 来检查是否有负面的后视,断言您不会匹配“空”行:

      perl -pe 's/(?<!$)(.*)/"\1"/' file
      

      正如@edmorton 在他的回答中所建议的那样,另一种选择是在您的正则表达式中更加具体。

      【讨论】:

        【解决方案6】:

        在 gnu sed 上试过

        sed -E "s/\S+/'&'/" file.txt
        

        【讨论】:

        • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        • @nircraft 对此添加解释就像向 i++ 添加评论一样——完全没用。当您查看自动工具放入可能低质量队列的帖子时,如果您不知道该域,那么您将无法帮助确定真正低质量的答案与例如,那些作为纯代码就很好的那些,所以只需继续列表中的下一个。
        猜你喜欢
        • 2015-11-14
        • 2011-09-27
        • 2016-08-15
        • 1970-01-01
        • 2010-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-10
        相关资源
        最近更新 更多