【问题标题】:String Replace | Shell/bash file字符串替换 |外壳/bash 文件
【发布时间】:2019-05-19 19:40:59
【问题描述】:

我正在尝试使用 sh 文件中的 sed 替换字符串。

问题:'connection' 后有空行,并且它的'-url' 字符串出现在下一行,此外还需要替换端口号和密码字符串。使用 sed 我无法在连接后删除空白行。

原字符串:

connection

-url>jdbc:oracle:thin:@10.10.10.11\:1551/password1 /connection-url

替换为

connection-url>jdbc:oracle:thin:@10.10.10.90\:1555/password2 /connection-url

我尝试了以下不起作用的命令:

sed -i 's/connection[\t ]+/,/g' sed-script.sh

sed 's/\connection*-\connection*/-/g' sed-script.sh 

【问题讨论】:

  • 这看起来一点也不像 XML。请edit 显示您尝试的sed 命令的问题,并解释它是如何失败的。如果这真的是 XML,你为什么不使用像 xmlstarlet 这样的 XML 工具?
  • @tripleee:它是 shell 文件,更新了我尝试在连接后替换空白/空格的命令
  • 顺便说一句,您的sed 可能不理解\t。但正如我在回答中所概述的那样,问题比这更根本。
  • 您的示例显示 password1 被替换为 password2 以及“连接”和“-url”之间的空格被删除。如果这是您问题的一部分,请在散文讨论中也包含对此的描述。
  • IP 地址也在输入和输出之间变化。修复您的示例或更新文本以阐明这些更改的标准。

标签: string awk sed str-replace


【解决方案1】:

sed 默认一次处理一行;如果你想检查一个空行是否跟随另一行,你必须编写一个sed 脚本来实现它。

我会使用 Awk 或 Perl 来代替这个特定的任务。

perl -p0777 -i -e 's/connection\n\n-url/connection-url/' file

awk '/^connection/ { c=1; next }
    c && /^$/ { c++; next }
    c && /^-url/ { $1="connection" $1; c=0 }
    c { print "connection-";
        while(--c) print "" }
    1' file >file.new

Perl 和sed 一样,有一个-i 选项来就地替换文件。 GNU Awk 有一个扩展来做同样的事情(查找-i inplace),但它不能移植到较小的 Awks。

Perl 的-0777 选项会导致整个文件作为单个“行”、换行符 (\n) 和所有内容被吞入内存。如果文件很大,这显然是有问题的。

如果结果是错误匹配,Awk 脚本会小心放回它跳过的行。

【讨论】:

  • 嗨@triplee,执行了上面提到的awk脚本,但没有成功。脚本: awk '/connection- */ { c=1;下一个 } c && /^$/ { c++;下一个 } c && /^-url/ { $1="connection-url"; c=0 } c { 打印“连接-”; while(--c) print "" } 1' connection-string.sh >/tmp/file1.sh cat /tmp/file1.sh 输出:
  • 抱歉,第一行 /^connection/ 的正则表达式错误。现在更新了。 Perl 脚本还需要一个小修复——很抱歉,当我最初编写它时,我不在一个可以测试它的地方。
【解决方案2】:

sed -

sed -E '
  /connection$/,/^-url/ {
    /connection$/ { h; d; }
    /^$/            d
    /^-url/       { H; s/.*//; x; s/\n//g; }
  }
' old > new

假设没有杂散的空白,并且 connection 单独一行应该后跟以 -url 开头的行...

【讨论】:

    【解决方案3】:

    您可以使用tr 删除“连接”后的空白行。

    echo <input string> | tr -d "\n"

    通过od -c 运行字符串,我们可以看到我们想要\n 字符:

    0000000 c o n n e c t i o n \n \n - u r l 0000020 > j d b c : o r a c l e : t h i 0000040 n : @ 1 0 . 1 0 . 1 0 . 1 1 \ : 0000060 1 5 5 1 / p a s s w o r d 1 / 0000100 c o n n e c t i o n - u r l \n

    【讨论】:

    • 这将删除所有换行符,包括终止行,使文件作为 POSIX 文本文件无效。
    • 如果需要,您可以使用echo "" >> file.txt 添加终止换行符。
    • 或者对于单行,将输出通过管道传输到 echo 会附加一个 \n 字符:echo <input string> | tr -d "\n"| xargs echo
    • 其实echo是多余的; xargs 没有参数默认运行(尽管这可以说是晦涩难懂的)。
    【解决方案4】:

    使用 GNU awk 测试。

    awk -v RS="\n+{n}" '{$1=$1} 1'  Input_file
    connection -url>jdbc:oracle:thin:@10.10.10.11\:1551/password1 /connection-url
    

    请您尝试关注一次。

    awk '/^connection/{val=$0;next} NF && /^-url/{print val $0;val=""}' Input_file
    

    输出如下。

    connection-url>jdbc:oracle:thin:@10.10.10.11\:1551/password1 /connection-url
    

    【讨论】:

    • 第一个脚本将丢失所有空行。第二个脚本将丢失一个connection,后面没有-url
    • @RavinderSingh13:请查看两个脚本输出的详细信息。正如三重脚本 1 正确提到的那样: awk -v RS="\n+{n}" '{$1=$1} 1' connection-string.sh 输出:jdbc:oracle:thin:@10.10.10.11 \:1551/password1 /connection-url> 问题:它在连接和 url 脚本 2 之间保留空间: awk '/^connection/{val=$0;next} NF && /^-url/{print val $0;val=" "}' connection-string.sh 输出:-url>jdbc:oracle:thin:@10.10.10.11\:1551/password1 /connection-url> 问题:它删除连接
    • @user3817627,您能否使用` 反引号将您的 cmets 包含在代码标签中,因为我不清楚。
    • @RavinderSingh13:请查看详细信息: 脚本 1:awk -v RS="\n+{n}" '{$1=$1} 1' connection-string.sh 输出:jdbc:oracle:thin:@10.10.10.11\:1551/password1 /connection-url> 问题:它在连接和 url 之间保留空间 脚本 2:awk '/^connection/{val=$0;next} NF && /^-url/{print val $0;val=""}' connection-string.sh 输出:-url>jdbc:oracle:thin:@10.10.10.11\:1551/password1 /connection-url> 问题:它删除连接
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 2021-02-28
    • 2015-07-07
    • 1970-01-01
    • 2012-04-21
    • 2011-10-19
    相关资源
    最近更新 更多