Perl 在文件中的指定行后插入文本

Perl 在文件中的指定行后插入文本,perl,awk,sed,Perl,Awk,Sed,我需要支持来执行以下任务,因为一个文件包含大约5000行 输入 输出 cp abc/P_10_10A.pdb lig.pdb cp abc/protein.pdbqt . cp abc/run.pl . ./run.pl mv *.* P_10_10A cp abc/P_10_11A.pdb lig.pdb cp abc/protein.pdbqt . cp abc/run.pl . ./run.pl mv *.*

我需要支持来执行以下任务,因为一个文件包含大约5000行

输入

输出

    cp abc/P_10_10A.pdb lig.pdb
    cp abc/protein.pdbqt .
    cp abc/run.pl .
    ./run.pl
    mv *.* P_10_10A

    cp abc/P_10_11A.pdb lig.pdb
    cp abc/protein.pdbqt .
    cp abc/run.pl .
    ./run.pl
    mv *.* P_10_11A

    cp abc/P_10_11B.pdb lig.pdb
    cp abc/protein.pdbqt .
    cp abc/run.pl .
    ./run.pl
    mv *.* P_10_11B
我可以加mv。如下

    sed '0~4 a\mv *.*  \'       text_file.sh

剩下的我怎么办?非常感谢。

这适用于
perl
中给定的
数据

#!/usr/bin/perl

use strict;
use warnings;

open my $IN, "<", "test";
open my $OUT, ">", "test_new";
my $insert;
while (my $line = <$IN>){
    chomp($line);

    if($line =~ m/cp abc\/(.*).pdb lig.pdb$/){
        $insert = $1;
    }

    if($line =~ m/    \.\/run\.pl/){
        $line = $line."\n".'    mv *.* '.$insert;
    }
    print $OUT $line."\n";
}
close $IN;
close $OUT;

一行

awk -F'[/.]' '!s && /cp/{s=$2;}s && /\.\/run\.pl/{$0=$0 RS "mv *.* "s;s=""}1' file
解释

awk -F'[/.]' '                    # -F set field sep forward slash or dot
      !s && /cp/{                 # if s is not set and cp word found
             s=$2                 # Assign second column value to s
      }
      s && /\.\/run\.pl/{         # when s is set and ./run.pl found
        $0 = $0 RS "mv *.* "s     # append current record with mv *.* value to s
        s=""                      # Reset s
      }1                          # perform default operation print $0
     ' file                       # Input file
输入

$ cat f
cp abc/P_10_10A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl 

cp abc/P_10_11A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl

cp abc/P_10_11B.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl
$ awk -F'[/.]' '!s && /cp/{s=$2}s && /\.\/run\.pl/{$0 = $0 RS "mv *.* "s; s=""}1' f
cp abc/P_10_10A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl 
mv *.* P_10_10A

cp abc/P_10_11A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl
mv *.* P_10_11A

cp abc/P_10_11B.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl
mv *.* P_10_11B
$0=$0 RS "    mv *.* "s;
输出

$ cat f
cp abc/P_10_10A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl 

cp abc/P_10_11A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl

cp abc/P_10_11B.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl
$ awk -F'[/.]' '!s && /cp/{s=$2}s && /\.\/run\.pl/{$0 = $0 RS "mv *.* "s; s=""}1' f
cp abc/P_10_10A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl 
mv *.* P_10_10A

cp abc/P_10_11A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl
mv *.* P_10_11A

cp abc/P_10_11B.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl
mv *.* P_10_11B
$0=$0 RS "    mv *.* "s;
对于空格,请修改此语句

$ cat f
cp abc/P_10_10A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl 

cp abc/P_10_11A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl

cp abc/P_10_11B.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl
$ awk -F'[/.]' '!s && /cp/{s=$2}s && /\.\/run\.pl/{$0 = $0 RS "mv *.* "s; s=""}1' f
cp abc/P_10_10A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl 
mv *.* P_10_10A

cp abc/P_10_11A.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl
mv *.* P_10_11A

cp abc/P_10_11B.pdb lig.pdb
cp abc/protein.pdbqt .
cp abc/run.pl .
./run.pl
mv *.* P_10_11B
$0=$0 RS "    mv *.* "s;
sed版本

sed '/^[[:blank:]]*cp /,/^[[:blank:]]*\./ {
      H
      /^[[:blank:]]*\./!d
      s/.*//;x
      s#^\(\(.[[:blank:]]*\)cp \)\([^[:blank:]]*/\([^[:blank:]]*\)\)\(\.pdb.*\)#\1\3\5\2mv *.* \4#
      }' YourFile
信息:

  • 按照段落(
    /^[:blank:][]*cp/,/^[:blank:][]*\./
    )从第一个cp开始,直到第二个cp/
  • 将每行添加到保留缓冲区(
    H
  • 如果不是段落的最后一行,则从当前工作缓冲区中删除该行(因此不再执行任何操作并循环读取下一行)(
    /^[:blank:][]*\./!d
  • 清空行并交换缓冲区内容(
    s/*/;x
  • 提取段落的文件名,并用
    mv
    info(
    s#^\([[:blank:]*\)cp\)\([^[:blank:]*/\([^[:blank:]]*\)\(\.pdb.\)\\1\3\5\2mv*\4
    )将其添加到末尾。这个正则表达式有一些特殊的信息

    • 有一个新行作为第一个字符(由于第一个
      H
      而不是
      H
    • 我使用几个子组轻松地将它们用作模式,就像第二个组一样,一条新线和第一个组中包含的第一系列空间(如果有的话)
  • 让sed打印结果

    • 修改段
    • 段落之间未触及的线条,如空行

awk版本

awk -F '[/.]' '
   /cp / {f[n++]=$2}
   /\.\/run/ {print;sub( /\..*/, "mv *.* " f[n=0])}
   7
   ' YourFile
信息:

  • 使用
    /
    作为字段分隔符(
    -F'[/.]'
  • 对于具有cp的每一行,将文件夹名称保留在增量数组中(第一个索引=0)(
    /cp/{f[n++]=$2}
  • 对于带有
    /run
    :(
    /\.\.\/run/{print;sub(/\..*/,“mv**”f[n=0])}
    )的每一行
    • 打印行
    • 将文本部分替换为
      mv…
    • 好名字总是f[0]
    • 同时重置索引(
      n=0
  • 打印行
    7

这种Perl方法需要命令行上输入文件的路径,并将输出发送到stdout

使用严格;
使用“全部”警告;
本地$/=”;
而(){
if(m |\b cp\s+(?:\w+/)*(\w+)| x){
my$pdb=$1;
s/*\s\K/\nmv*$pdb/xs;
}
印刷品;
}
输出
cp abc/P_10_10A.pdb lig.pdb
cp abc/protein.pdbqt。
cp abc/run.pl。
/run.pl
mv**P_10_10A
cp abc/P_10_11A.pdb lig.pdb
cp abc/protein.pdbqt。
cp abc/run.pl。
/run.pl
mv**P_10_11A
cp abc/P_10_11B.pdb lig.pdb
cp abc/protein.pdbqt。
cp abc/run.pl。
/run.pl
mv**P_10_11B

不理解否决投票的原因,否决投票人请让我知道这里出了什么问题我没有否决答案,但给定的输出在以
mv**P\u 10\u 11B开头的行前不包含
空格
@AbhiNickz:如果需要空格,请这样修改
$0=$0 RS“mv*”
,将空格放在
mv*
之前。您需要在多行模式下工作,或使用保留缓冲区保留文件夹名称。另外,使用
a
您不能修改此附加行的内容,它仅在ouptut stream中,不在当前工作缓冲区中。数据中的前导空格是否真的存在?空白行真的存在吗?我不能解释投票的下限,但是你的代码非常不流行。当OP数据中的前导空格可能根本不存在时,它也会精确匹配空格的数量。您的第二个
if
也应该是
elseif
。如果你想进行彻底的分析,请把它挂上。谢谢@Borodin提供的分析,我会记住这一点。