Reputation: 755
I have a huge file containing datasets such as:
100 S|||
100 S|d1|||88|||
100 S|0d|f6||f630|589f||
I need to replace |||
with |||||||
, only if the line contains no more pipes other than a single |||
sequence.
I tried using sed command for this requirement:
sed -i 's/|||/|||||||/g' input.txt
However, it is changing records in second line as well, which is not intended.
What would be the correct command usage? Any help will be highly appreciated.
Upvotes: 1
Views: 51
Reputation: 58351
This might work for you (GNU sed):
sed '/^[^|]*|||[^|]*$/s/|||/&&|/' file
If a line only contains 3 consecutive |
's, replace them by 7 |
's.
Upvotes: 0
Reputation: 133428
With awk
, you could try following. Written and tested with shown samples in GNU awk
.
awk 'gsub(/\|/,"&")==3{gsub(/\|\|\|/,"&||||")} 1' Input_file
Explanation: Adding detailed explanation for above.
awk ' ##Starting awk program from here.
gsub(/\|/,"&")==3{ ##checking if line has only 3 ||| then do following.
gsub(/\|\|\|/,"&||||") ##Globally substituting ||| with itself and |||| here.
}
1 ##printing current line here.
' Input_file ##Mentioning Input_file name here.
Upvotes: 1
Reputation: 784898
You can use this sed
command with capture groups to match non-pi[e characters before and after |||
:
sed -E 's/^([^|]*)(\|\|\|)([^|]*)$/\1\2||||\3/' file
100 S|||||||
100 S|d1|||88|||
100 S|0d|f6||f630|589f||
Details:
^
: Start([^|]*)
: Match 0 or more non-pipe characters in capture group #1(\|\|\|)
: Match 3 pipe characters in capture group #2([^|]*)
: Match 0 or more non-pipe characters in capture group #3$
: End\1\2||||\3
is replacement pattern that inserts ||||
after back-reference #2 i.e. \2
while putting back \1
and \3
as is.Upvotes: 2