Perl 在文件中的指定行后插入文本
我需要支持来执行以下任务,因为一个文件包含大约5000行 输入 输出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 *.*
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提供的分析,我会记住这一点。