Title: insert text after specified lines in a file
Tags: perl;awk;sed
Question: I need support to do the following task for a file contains around 5000 lines.
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
output
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
I could add mv . as follows..
sed '0~4 a\mv *.*  \'       text_file.sh
How can I do the rest? thanks a lot.
Comment: you need to work in multiline mode or using holding buffer to keep the folder name. Also, with a `a` you can't modify the content of this appended line, it's only in ouptut stream, not in current working buffer

Comment: Are the leading spaces in your data really there? Are the blank lines really there?

Here is the accepted answer: One liner
awk -F'[/.]' '!s &amp;&amp; /cp/{s=$2;}s &amp;&amp; /\.\/run\.pl/{$0=$0 RS "mv *.* "s;s=""}1' file
Explanation
awk -F'[/.]' '                    # -F set field sep forward slash or dot
!s &amp;&amp; /cp/{                 # if s is not set and cp word found
s=$2                 # Assign second column value to s
}
s &amp;&amp; /\.\/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
Output
$ awk -F'[/.]' '!s &amp;&amp; /cp/{s=$2}s &amp;&amp; /\.\/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
For space modify this statement
$0=$0 RS "    mv *.* "s;
Comment for this answer: I didn't downvoted the answer but given output doesn't contains `space` before lines starting with `mv *.* P_10_11B`.
Comment for this answer: Did not understand the reason for down vote, down voter please let me know what's wrong here
Comment for this answer: @AbhiNickz : If you need space please modify like this `$0=$0 RS "    mv *.* "s;` , put space just before `mv *.*`

Here is another answer: a sed version
sed '/^[[:blank:]]*cp /,/^[[:blank:]]*\./ {
H
/^[[:blank:]]*\./!d
s/.*//;x
s#^\(\(.[[:blank:]]*\)cp \)\([^[:blank:]]*/\([^[:blank:]]*\)\)\(\.pdb.*\)#\1\3\5\2mv *.* \4#
}' YourFile
proceed by paragraph (/^[[:blank:]]*cp /,/^[[:blank:]]*\./) from first cp until ./
add each line to holding buffer (H)
if not last line of paragraph, delete the line from current work buffer (so do nothing more and cycle with a read of next line) (/^[[:blank:]]*\./!d)
empty the line and swap buffer content (s/.*//;x)
extract the file name of the paragraph and add it to the end with the mv info (s#^\(\(.[[:blank:]]*\)cp \)\([^[:blank:]]*/\([^[:blank:]]*\)\)\(\.pdb.*\)#\1\3\5\2mv *.* \4#). This regex is the tricky one with some special info
there is a new line as 1st character (due to first H and not h)
i use several subgroup to use them as pattern easily like the second group, a new line and first series of space (if any) that is included in 1st group
let sed print the result
modified paragraph
untouched line like empty lines between paragraph
an awk version
awk -F '[/.]' '
/cp / {f[n++]=$2}
/\.\/run/ {print;sub( /\..*/, "mv *.* " f[n=0])}
' YourFile
use . and / as field separator (-F '[/.]')
for each line with cp, keep folder name in and incremental array (first index = 0) (/cp / {f[n++]=$2})
for each line with ./run: (/\.\/run/ {print;sub( /\..*/, "mv *.* " f[n=0])})
print the line
replace the text part with mv ...
the good name is always f[0]
reset the index in same time (n=0)
print the line 7

Here is another answer: This works for the given data in perl.
#!/usr/bin/perl
use strict;
use warnings;
open my $IN, "<", "test";
open my $OUT, "&gt;", "test_new";
my $insert;
while (my $line = <$IN&gt;){
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;
OUTPUT:
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
Comment for this answer: Thanks @Borodin for your given analysis, I will keep this in mind.
Comment for this answer: I can't account for the downvote, but your code is very non-Perlish. It also matches exact amounts of whitespace, when the leading spaces in the OP's data probably aren't even there. Your second `if` should also be an `elseif`. Put it up on [**Code Review**](http://codereview.stackexchange.com/) if you want a thorough analysis.

Here is another answer: This Perl approach expects the path to the input file on the command line and sends the output to stdout
use strict;
use warnings 'all';
local $/ = "";
while ( <&gt; ) {
if ( m| \b cp \s+ (?: \w+ / )* (\w+) |x ) {
my $pdb = $1;
s/ .* \S \K /\nmv *.* $pdb/xs;
print;
output
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

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 4, 'CommentCount': 2, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2017:00:01/13/17', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<perl><awk><sed>', 'Title': 'insert text after specified lines in a file', 'ViewCount': 121, 'id': 41632817, 'user_AboutMe': None, 'user_AccountId': 2501203.0, 'user_DisplayName': 'user2176228', 'user_Reputation': 307.0, 'user_Views': 62.0, 'user_id': 2176228.0}}