如何使用sed或awk在文件的特定行插入特定字符?

时间:2019-06-27 05:06:56

标签: bash unix awk sed

我想使用命令来编辑文件的特定行,而不是使用vi。就是这个如果从行开始有#,请替换#以使其取消注释。否则,添加#使其成为注释。我想使用sed或awk。但它不能按预期工作。
这是file

what are you doing now?
what are you gonna do? stab me?
this is interesting.
This is a test.
go big
don't be rude.

例如,如果它不是以#开头,我只想在第4行This is a test的开头添加#。如果它以#开头,请删除#

我已经尝试通过sed&gawk(awk)

gawk -i inplace '$1!="#" {print "#",$0;next};{print substr($0,3,length-1)}' file 
sed -i /test/s/^#// file  # make it uncomment

sed -i /test/s/^/#/ file  # make it comment

我不知道如何使用if else使sed工作。我只能用一个命令来完成,然后使用另一个正则表达式进行相反的操作。
使用gawk,它将作为主线。但这会弄乱其余的代码。

4 个答案:

答案 0 :(得分:2)

这将从第4行的开头删除#或将其添加到第4行的开头:

sed -i '4s/^#/\n/; 4s/^[^\n]/#&/; 4s/^\n//' File

以上假设为GNU sed。如果您使用的是BSD / MacOS sed,则需要进行一些小的更改。

当sed读取新行时,我们肯定知道新行的一件事是它包含\n。 (如果是这样,它将是两行,而不是一行。)使用此知识,脚本可以通过以下方式工作:

  • s/^#/\n/

    如果第四行以#开头,请将#替换为\n。 (\n表示该行最初已被注释掉。)

  • 4s/^[^\n]/#&/

    如果第四行现在以\n以外的其他内容开头(表示它最初未被注释),请在前面放置#

  • 4s/^\n//

    如果第四行现在以\n开头,请将其删除。

替代:修改包含test

的行

要注释/取消注释包含test的行:

sed  '/test/{s/^#/\n/; s/^[^\n]/#&/; s/^\n//}' File

替代:使用awk

使用awk可以应用完全相同的逻辑。如果我们要注释/取消注释第4行:

awk 'NR==4 {sub(/^#/, "\n"); sub(/^[^\n]/, "#&"); sub(/^\n/, "")} 1' File

如果我们要注释/取消注释包含test的任何行:

awk '/test/ {sub(/^#/, "\n"); sub(/^[^\n]/, "#&"); sub(/^\n/, "")} 1' File

替代:使用sed但不使用换行符

要注释/取消注释包含test的任何行:

sed  '/test/{s/^#//; t; s/^/#/; }' File

工作原理:

  • s/^#//; t

    如果该行以#开头,则将其删除。

    t告诉sed,如果替换成功,则应跳过其余命令。

  • s/^/#/

    如果执行此命令,则表示替换未成功(这意味着该行最初未被注释掉),因此我们插入了#

答案 1 :(得分:2)

这可能对您有用(GNU sed):

sed '4{s/^/#/;s/^##//}' file

在第4行上,将#放在该行的前面,如果有2 #,则将其删除。

也可以这样写:

sed '4s/^/#/;4s/^##//' file

答案 2 :(得分:0)

如果最终使用的sed系统不支持就地编辑,则可以退回到其叔叔ed

ed -s file 2>/dev/null <<EOF
4 s/^/#/
s/^##//
w
q
EOF

(标准错误被重定向到/dev/null,因为在ed中,与sed不同的是,如果s不替换任何内容并因此打印了问号,则表示错误到标准错误。)

答案 3 :(得分:0)

public DataTable exeReader(string cmd, OleDbParameter[] param)
{
    using(OleDbConnection oConn = new OleDbConnection(connString))
    {
        DataTable AppData = new DataTable();
        oConn.Open();
        var oCmd = oConn.CreateCommand();
        oCmd.CommandText = cmd;

        try
        {
            using(var oReader = oCmd.ExecuteReader()) {
                AppData.Load(oReader);
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message);
        }
    }
    return AppData;
}