Shell 将一个文件的内容复制到另一个文件中相对于文件末尾的位置

Shell 将一个文件的内容复制到另一个文件中相对于文件末尾的位置,shell,awk,sed,posix,sh,Shell,Awk,Sed,Posix,Sh,StackExchange新手,请原谅我的错误 我有一个输入文件,需要在最后一个字符之前复制到另一个文件中 inputfile.txt: input { "inputstuff" } filetowriteto.txt: Stuff { foo { "foostuff" } bar { "barstuff" } } Stuff { foo {

StackExchange新手,请原谅我的错误

我有一个输入文件,需要在最后一个字符之前复制到另一个文件中

inputfile.txt:

input {
       "inputstuff"
}
filetowriteto.txt:

Stuff {
       foo {
            "foostuff"
       }
       bar {
            "barstuff"
       }
}
Stuff {
       foo {
            "foostuff"
       }
       bar {
            "barstuff"
       }
       input {
              "inputstuff"
       }
}

运行脚本后,生成的文件现在应该是:

filetowriteto.txt:

Stuff {
       foo {
            "foostuff"
       }
       bar {
            "barstuff"
       }
}
Stuff {
       foo {
            "foostuff"
       }
       bar {
            "barstuff"
       }
       input {
              "inputstuff"
       }
}

基本上,脚本会复制
输入
行集,并将它们粘贴到
filetowriteto.txt中最后一个右括号之前

脚本不能依赖行数,因为
filetowriteto.txt
没有可预测的foo或bar行数,我不知道如何使用sed或awk来完成此操作。

尝试:

$ awk 'FNR==NR{ if (NR>1) print last; last=$0; next} {print "       " $0} END{print last}' filetowriteto.txt inputfile.txt 
Stuff {
       foo {
            "foostuff"
       }
       bar {
            "barstuff"
       }
       input {
              "inputstuff"
       }
}
要就地更改文件,请执行以下操作:

awk 'FNR==NR{ if (NR>1) print last; last=$0; next} {print "       " $0} END{print last}' filetowriteto.txt inputfile.txt >tmp && mv tmp filetowriteto.txt
工作原理
  • FNR==NR{if(NR>1)最后一次打印;最后一次=$0;下一次}

    读取第一个文件时,(a)如果我们不在第一行,则打印
    last
    的值,(b)将当前行的文本指定给
    last
    ,以及(c)跳过其余命令并跳到
    下一行

    这使用了一个常见的awk技巧。只有在读取第一个文件时,条件
    FNR==NR
    才为真。这是因为,在awk中,NR是我们迄今为止读取的行数,而FNR是我们迄今为止从当前文件读取的行数。因此,
    FNR==NR
    只有在我们从第一个文件读取时才是真的

  • print”“$0

    在读取第二个文件时,打印每一行的前导空格

  • END{print last}

    打印完第二个文件后,打印第一个文件的最后一行

    • 给定:

      $ cat /tmp/f1.txt
      input {
             "inputstuff"
      }
      $ cat /tmp/f2.txt
      Stuff {
             foo {
                  "foostuff"
             }
             bar {
                  "barstuff"
             }
      }
      
      您可以使用来实现这一点:

      $ ( sed '$d' f2.txt ; cat f1.txt ; tail -n1 f2.txt ) 
      
      或(此版本不创建子shell)

      它是如何工作的

    • sed'$d'f2.txt
      打印f2.txt的最后一行以外的所有内容

    • cat f1.txt
      在该点打印f1.txt

    • tail-n1 f2.txt
      现在打印f2的最后一行

    • 如果要缩进f1.txt,请使用sed而不是cat。您还可以使用sed打印最后一行:

      $ { sed '$d' /tmp/f2.txt ; sed 's/^/       /' /tmp/f1.txt ; sed -n '$p' /tmp/f2.txt;  } 
      Stuff {
             foo {
                  "foostuff"
             }
             bar {
                  "barstuff"
             }
             input {
                    "inputstuff"
             }
      }
      
      然后,如果愿意,可以使用
      重定向将分组的输出重定向到文件

      $ cat tst.awk
      NR==FNR {
          rec = (NR>1 ? rec ORS : "") $0
          next
      }
      FNR>1 {
          print prev
          if ( sub(/[^[:space:]].*/,"",prev) ) {
              indent = prev
          }
      }
      { prev=$0 }
      END {
          gsub(ORS,ORS indent,rec)
          print indent rec ORS prev
      }
      
      $ awk -f tst.awk inputfile.txt filetowriteto.txt
      Stuff {
             foo {
                  "foostuff"
             }
             bar {
                  "barstuff"
             }
             input {
                    "inputstuff"
             }
      }
      
      上面使用要修改的文件最后一行之前的最后一个非空行的缩进,为插入的新文件设置缩进