0

I have a file like this:

1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211
3;1471383211;frank;WO12345;1471385211
4;1471385311;frank;WO12345;
5;1471385311;joe;WO12346;1471388211

I'd like to use a bash script to find the line that contains a specified name (like frank) as well as a specified WO number (like WO12345) and also ends with a ;, then add a string to the end of the line. I want to edit the file directly, not output to stdout. I know how to use read to get the name and WO number. I'm guessing sed with -i is the right tool. How can I do that?

1
  • 3
    Your example is confusing me. Please show us a before and after example. Ideally you should show us what you tried that didn't work as this is not a script writing service (even if the question is simple). Commented Aug 17, 2016 at 18:49

2 Answers 2

2

If the name and WO are always consecutive, it's quite straightforward:

sed  '/frank;WO12345;/s/;$/;sometext/' -i file

If they can appear either way around, or not necessarily next to each other, use blocks of commands to combine the two tests:

sed  '/;frank;/{/;WO12345;/s/;$/;sometext/}' -i file
3
  • Thanks, that works. Will this rewrite the entire file? If I can, I'd like to only write sometext because my file might be pretty big. Commented Aug 17, 2016 at 19:01
  • 1
    @aswine What do you mean by "only write sometext"? It's inserting text; everything after it will now be a bit later in the file. It might depend on your filesystem, but whatever method you pick, you will probably be rewriting the whole file from that point all the way to the end. Commented Aug 17, 2016 at 19:04
  • 1
    @aswine sed -i will just write to a temporary file then, when it's done, move that temporary file over the original. There aren't many ways around this no matter what tool you use. Commented Aug 17, 2016 at 19:05
1

awk is better suited for field separated data.

Using awk:

awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt

replace ;Foobar with what you want to insert at the end.

Here we are checking if ; separated 3rd and 4th fields match out desired strings, if so string ;Foobar is added at the end.

Latest GNU awk (>=4.10) has inplace editing option:

awk -i inplace -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt

If you don't have that use sponge from GNU moreutils or a temporaruy file:

awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt | sponge file.txt

awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' \
       file.txt >file_temp.txt && mv file_temp.txt file.txt

If you insist on sed:

sed -Ei '/^([^;]*;){2}frank;WO12345;/ s/$/;Foobar/' file.txt
  • ([^;]*;){2} matches first two fields and then we have checked if the 3rd and fourth fields are desired and then the replacement is done

Example:

$ cat file.txt
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211
3;1471383211;frank;WO12345;1471385211
4;1471385311;frank;WO12345;
5;1471385311;joe;WO12346;1471388211

$ awk -F';' '$3=="frank" && $4="WO12345" {print $0 ";Foobar"}' OFS=';' file.txt
2;1471378551;frank;WO12345;1471380211;Foobar
3;1471383211;frank;WO12345;1471385211;Foobar
4;1471385311;frank;WO12345;;Foobar

$ sed -E '/^([^;]*;){2}frank;WO12345;/ s/$/;Foobar/' file.txt
1;1471375551;joe;WO12344;
2;1471378551;frank;WO12345;1471380211;Foobar
3;1471383211;frank;WO12345;1471385211;Foobar
4;1471385311;frank;WO12345;;Foobar
5;1471385311;joe;WO12346;1471388211

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.