If pattern match in other column, modify column 3.

My command sed will modify everything in column 3 if i will use the command below. I want to search for a pattern then modify everything in column 3.

sed -i 's/\|165\|/server1/g' file.txt

Input:
01-31-2019 19:14:05|device|165|1548962040165|5c5348f9-0804-1111|file_attach|7271|587|smtp|
01-31-2019 19:14:05|device|165|1548962040165|5c5348f9-0804-1234|file_attach|7271|587|smtp|
01-31-2019 19:14:05|device|165|1548962040028|5c5348f9-0804-6789|file_attach|7271|587|smtp|
01-31-2019 19:14:05|device|165|1548165040028|5c5348f9-0804-1111|file_attach|7271|587|smtp|

Output:
01-31-2019 19:14:05|device|server1|1548962040028|5c5348f9-3-4-0804-1111|file_attach|7271|587|smtp|
01-31-2019 19:14:05|device|165|1548962040028|5c5348f9-3-4-0804-1234|file_attach|7271|587|smtp|
01-31-2019 19:14:05|device|165|1548962040028|5c5348f9-5-6-0804-6789|file_attach|7271|587|smtp|
01-31-2019 19:14:05|device|server1|1548962040028|5c5348f9-1-2-0804-1111|file_attach|7271|587|smtp|

how about to start with - you may have to make slight adjustments based your more detailed requirements:

awk -F'|' '$5~(pat "$"){$3=ser}1' pat=1111 ser=server1 OFS='|' myFile
2 Likes

You may pimp up your own approach by adding an address specification. Be aware that it will NOT change the third field if that doesn't contain 165 , or change any other field that holds that value.

sed -r '/([^|]*\|){4}[^|]*1111\|/ s/\|165\|/|server1|/' file
01-31-2019 19:14:05|device|server1|1548962040165|5c5348f9-0804-1111|file_attach|7271|587|smtp|
01-31-2019 19:14:05|device|165|1548962040165|5c5348f9-0804-1234|file_attach|7271|587|smtp|
01-31-2019 19:14:05|device|165|1548962040028|5c5348f9-0804-6789|file_attach|7271|587|smtp|
 01-31-2019 19:14:05|device|server1|1548165040028|5c5348f9-0804-1111|file_attach|7271|587|smtp|

EDIT: If you want to replace field 3 regardless of its contents, try

sed -r '/([^|]*\|){4}[^|]*1111\|/ s/(([^|]*\|){2})[^|]*\|/\1server1|/' file

P.S.: you might want to adapt the title of your thread.

2 Likes

Maybe I misunderstood something. Here are my drop

sed '/-1111|/ s/|165|/|server1|/' file

--- Post updated at 23:34 ---

You can be safe as it is. I think that will be enough

sed '/-1111|/ s/e|165|/e|server1|/' file
1 Like

And I understood, the whole thing is exactly the coincidence of the fields :slight_smile:

sed -r 's/(([^|]*\|){2})165((\|[^|]*){2}1111)/\1server1\3/' file
1 Like

Hi Neza,
care to explain the solution, character by character?
Thank you

--- Post updated at 12:28 AM ---

HI Vgersh,
care to explain the solution, character by character?
Thank you

--- Post updated at 12:28 AM ---

Hi Rudi,
care to explain the solution, character by character?
Thank you

--- Post updated at 12:29 AM ---

Hi Rudi,
care to explain the solution, character by character?
Thank you

Now, this might become lengthy and tedious. Some hints, maybe, c.f. man sed for further reference / explanation:

sed -r '/([^|]*\|){4}[^|]*1111\|/ s/\|165\|/|server1|/' file
sed -r '/([^|]*\|){4}[^|]*1111\|/ s/(([^|]*\|){2})[^|]*\|/\1server1|/' file

-r : switch sed to use EREs
{...} : "bound"; repetition factor of preceding expression
(...) : "atom", also "parenthesized subexpression"; to be used by "back reference"
[...] : "bracket expression"
\| : escaped pipe, to be taken as a literal character, as opposed to the alternate operator |
\1 : "back reference".