使用bash中的变量行号更改特定的文本行

时间:2017-05-01 04:21:04

标签: bash shell

我正在为我正在运行的家庭服务器上的项目工作,我需要更改配置文件中特定行的文本。我需要更改的行有一个具有不同值的唯一属性名称,但有时新行将添加到文件中,导致我想要更改的行的位置不时移动。 为了编写和测试脚本,我在我的电脑上选择了一个随机配置文件,看起来像这样

# cat kvirc4.ini
# KVIrc configuration file
[Main]
LocalKvircDirectory=C:\Users\Aulus\AppData\Roaming\KVIrc4\
SourcesDate=538186288

我编写了一个脚本,将第3行的内容更改为“已更改”。如果我编写这样的脚本,直接在脚本中指定行号,它按预期工作,输出文件显示源文件中的那一行改变了一行。

# cat bashscript.sh
#!/bin/bash
awk '{ if (NR == 3) print "different"; else print $0}' kvirc4.ini.bak >   output

然而,一旦我添加一个命令来查找行号并将其保存到我在awk中使用的变量来指定行脚本,不再对该行进行更改而不保留文件的原始版本。我添加了你在下面看到的回声,以确认我的变量具有正确的值,它确实如此。在我看来,问题是我的awk命令没有正确读取行号导致if语句保持为假,但我仍然有点新的bash和awk所以我不知道如何解决它。任何人都可以提供建议,帮助我找到解决方案吗?

# cat bashscript.sh
#!/bin/bash
lineno=$(awk '/LocalKvircDirectory/{ print NR; exit }'  kvirc4.ini.bak);lineno=$(printf '%b' $lineno)
echo $lineno
# awk 'NR==$lineno {$0="changed"} { print }' kvirc4.ini.bak
awk '{ if (NR == "$lineno") print "different"; else print $0}' kvirc4.ini.bak > output

1 个答案:

答案 0 :(得分:0)

您正在使用bash参数扩展样式 ("$lineno")在awk代码中,没有任何关系。

您的"$lineno"永远不会展开,因为它是单引号。

您有几种选择:

  1. 您可以使用不同的引号使"$lineno"工作:

    awk '{ if (NR == '"$lineno"') print ···
    
  2. 在命令行中使用awk变量初始化

    awk -v lineno="$lineno" '{ if (NR==lineno) print ···
    
  3. 使用the ENVIRON awk array获取已导出(即在环境中)的bash变量的值:

    export lineno
    awk '{ if (NR==ENVIRON["lineno"]) print ···
    
相关问题