I want to delete all lines from first to till last occurrence line of matching pattern "1055/Rack2.txt" including this line. This pattern occurred three times in below data. Here is the data where I want to work with.
/root/monitor_data/hmc_temp/2023-01-06-1050/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1050/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1050/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1050/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1050/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1050/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1050/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1050/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack2.txt
I tried with below command, but it deletes only from first line to first occurrence of matching pattern. Deletion not done for next two occurrence.
sed -i '1,/1055\/Rack2/d' input.txt
and leaves two lines with same matching pattern and the output is below.
/root/monitor_data/hmc_temp/2023-01-06-1055/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1100/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1105/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack0.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack1.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack2.txt
/root/monitor_data/hmc_temp/2023-01-06-1110/Rack2.txt```
CodePudding user response:
If ed
is available/acceptable, something like:
printf '%b\n' '?1055\/Rack2?kx' "1;'xd" ,p Q | ed -s input.txt
A small explanation about the ed
code.
?pattern-goes-here?
is the same as/pattern-goes-here/
, only difference is the search starts from the last line of the buffer. The pattern is1055/Rack2
. Note the use of? ?
instead of/ /
.kx
Marks the line/string in the buffer, in this case whatever is matched by the?pattern-goes-here?
,k
is the command andx
is the marker.1;'xd
Is an address range separated by a;
e.g.start;end
The1
is the line number,'x
is how to call/evaluate/expand the marked line/string withkx
andd
means delete.So in the end it reads from line number 1, delete until it reaches the spot which is marked and x indeed marks the spot! ;-)
If in-place editing is required change
Q
tow
Remove the
,p
to silence the output.
CodePudding user response:
Here's a solution for awk:
tac test | awk '/1055\/Rack2.txt/{f=1}!f' | tac
This command starts printing lines after last match of /1055\/Rack2.txt/
.
CodePudding user response:
This might work for you (GNU sed):
sed 'H;/1055\/Rack2/{z;h};$!d;x;s/.//' file
Make a copy of the lines before 1055/Rack2
and replace those lines by a newline when the current line is 1055/Rack2
. At the end of the file, remove the newline at the start of the copy and print the remaining lines.
Alternative:
sed -z 's#.*1055/Rack2[^\n]*\n##' file
The -z
option slurps the whole file into memory. Since .*
is greedy it will remove everything upto the last occurrence of 1055/Rack2
. The [^\n]*\n
removes to the end of that line.