【问题标题】:Inserting a line with special characters (',`,$ etc) into a file using BASH使用 BASH 在文件中插入带有特殊字符('、`、$ 等)的行
【发布时间】:2020-05-24 23:14:37
【问题描述】:

您好,我需要一些 bash 脚本方面的帮助。

我需要将以下行插入文件中特定行号

su - test -c '$HOME/scripts/auto start' >> /home/test/auto_start.`date +%h_%d_%y`.log 2>&1

在更大的问题陈述中,要插入到指定的行号&到文件中,都是动态的&需要从 csv 文件中获取。

csv 文件如下所示:

$ cat test_file.csv
TARGET_NODE,TARGET_FILE,TARGET_LINE,NEW_LINE
10.10.10.10,test_file.csv,2,su - test -c '$HOME/scripts/auto start' >> /home/test/auto_start.`date +%h_%d_%y`.log 2>&1

已尝试以多种方式使用 sed,但都失败了。由于系统限制,我们不能使用python。

简单的测试方法:

seq 4|sed 's/<LINE_NUMBER>/<NEW_TEXT>/'

所以我们尝试使用:

seq 4|sed 's/2/'su - test -c '$HOME/scripts/auto start' >> /home/test/auto_start.`date +%h_%d_%y`.log 2>&1'/'

【问题讨论】:

  • “test_file.csv”暗示它应该更新自己(它在第 2 行引用自己)。如果你这样做,列结构将被破坏(test_file.csv 有 TARGET_NODE 列)。您能澄清一下您要做什么吗?
  • 目标节点 10.10.10.10 上的 test_file.csv 与本地文件不同。即使文件名相同,但它们位于不同的节点上。
  • 您必须澄清(在问题中)如何访问远程文件。否则,本地的 sed 将只能访问本地的 test_file.csv

标签: bash sed


【解决方案1】:

您没有说是否要在现有行之前或之后打印新行或代替现有行,所以这里是全部 3:

$ seq 4 | awk -F, 'NR==FNR{line[$3]=$4; next} FNR in line{print line[FNR]} 1' test_file.csv -
1
su - test -c '$HOME/scripts/auto start' >> /home/test/auto_start.`date +%h_%d_%y`.log 2>&1
2
3
4

.

$ seq 4 | awk -F, 'NR==FNR{line[$3]=$4; next} 1; FNR in line{print line[FNR]}' test_file.csv -
1
2
su - test -c '$HOME/scripts/auto start' >> /home/test/auto_start.`date +%h_%d_%y`.log 2>&1
3
4

.

$ seq 4 | awk -F, 'NR==FNR{line[$3]=$4; next} FNR in line{$0=line[FNR]} 1' test_file.csv -
1
su - test -c '$HOME/scripts/auto start' >> /home/test/auto_start.`date +%h_%d_%y`.log 2>&1
3
4

以上内容可以使用任何 shell 中的任何 awk 以及每个 UNIX 机器上来自该 CSV 的任何字符串

【讨论】:

    【解决方案2】:

    如果您对使用 perl 没有系统限制:

    #!/usr/bin/env bash
    seq 4 | perl -pe '
    BEGIN {
        open CSV, shift; # Open test_file.csv
        <CSV>; # Ignore first line
        # Get line number and command
        ($n, $c) = <CSV> =~ /^(?:[^,]+,){2}([^,]+),(.*)/;
        }
    { s/.*/$c/ if ($. == $n); } # Replace line with number $n
    ' test_file.csv
    

    【讨论】:

      【解决方案3】:

      只需正确引用该行并使用不同的s 命令分隔符,因为/ 用于替换字符串...转义替换字符串中的特殊正则表达式字符,如&amp;\

      $ seq 4 | sed 's~2~su - test -c '\''$HOME/scripts/auto start'\'' >> /home/test/auto_start.`date +%h_%d_%y`.log 2>\&1~'
      1
      su - test -c '$HOME/scripts/auto start' >> /home/test/auto_start.`date +%h_%d_%y`.log 2>&1
      3
      4
      

      awk:

      seq 4 | awk -vvar='su - test -c '\''$HOME/scripts/auto start'\'' >> /home/test/auto_start.`date +%h_%d_%y`.log 2>&1' 'NR==2{$0=var}1'
      

      我不鼓励使用反引号`。不要使用它们。请改用$(...)

      【讨论】:

      • 如果您在-vvar= 之间放置一个空格,那么该脚本将可移植到所有 POSIX(和其他)awk 而不是 gawk 特定的。
      猜你喜欢
      • 1970-01-01
      • 2015-03-04
      • 2015-02-05
      • 2023-01-19
      • 2021-03-28
      • 2011-12-10
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多