2

I have files with the following format: File name is file.txt

chr - seq1 NZ_JAHWGH010000010.1 0 60562 green_a4
chr - seq3 NZ_JAHWGH010000012.1 0 466573 green_a4
chr - seq5 NZ_JAHWGH010000013.1 0 125526 green_a4
chr - seq6 NZ_JAHWGH010000014.1 0 717625 green_a4
chr - seq7 NZ_JAHWGH010000015.1 0 209757 green_a4
chr - seq8 NZ_JAHWGH010000016.1 0 55318 green_a4
chr - seq9 NZ_JAHWGH010000017.1 0 467034 green_a4
chr - seq50 NZ_CAJGBF010000017.1 0 83173 green_a4
chr - seq51 NZ_CAJGBF010000018.1 0 76510 green_a4
chr - seq52 NZ_CAJGBF010000019.1 0 67820 green_a4
chr - seq54 NZ_CAJGBF010000021.1 0 61770 green_a4
chr - seq55 NZ_CAJGBF010000022.1 0 56876 green_a4
chr - seq56 NZ_CAJGBF010000023.1 0 50411 green_a4
chr - seq57 NZ_CAJGBF010000024.1 0 49535 green_a4

I want to change the name of row third column as seq1 if the name in column four starts with NZ_JAHWGH and seq2 if name starts with NZ_CAJGBF. I want output like this from the same file:

chr - seq1 NZ_JAHWGH010000010.1 0 60562 green_a4
chr - seq1 NZ_JAHWGH010000012.1 0 466573 green_a4
chr - seq1 NZ_JAHWGH010000013.1 0 125526 green_a4
chr - seq1 NZ_JAHWGH010000014.1 0 717625 green_a4
chr - seq1 NZ_JAHWGH010000015.1 0 209757 green_a4
chr - seq1 NZ_JAHWGH010000016.1 0 55318 green_a4
chr - seq1 NZ_JAHWGH010000017.1 0 467034 green_a4
chr - seq2 NZ_CAJGBF010000017.1 0 83173 green_a4
chr - seq2 NZ_CAJGBF010000018.1 0 76510 green_a4
chr - seq2 NZ_CAJGBF010000019.1 0 67820 green_a4
chr - seq2 NZ_CAJGBF010000021.1 0 61770 green_a4
chr - seq2 NZ_CAJGBF010000022.1 0 56876 green_a4
chr - seq2 NZ_CAJGBF010000023.1 0 50411 green_a4
chr - seq2 NZ_CAJGBF010000024.1 0 49535 green_a4

I tried these two commands but they didn't work:

awk 'BEGIN{FS=OFS=" "}($4 == /^NZ_JAHWGH/){$3==seq1}1' file.txt

awk 'BEGIN{FS=OFS=" "} {if ($4 ~ /^NZ_JAHWGH/) $3=seq1}1' file.txt
1
  • Do you have any input lines where $4 starts with nether of those 2 strings? If so, how should those be handled?
    – Ed Morton
    Mar 11 at 16:58

2 Answers 2

4

You first awk attempt:

awk 'BEGIN{FS=OFS=" "}($4 == /^NZ_JAHWGH/){$3==seq1}1' file.txt

fails because $3==seq1 is a test of whether $3 is exactly equal to the value of the variable seq1. What you wanted is = instead of == so you are setting the value, not testing it, and "seq1" to indicate that this is a string and not a variable.

Next, to check against a regular expression, you need ~ /regex/, not == /regex/. Your second attempt fails for the same reasons, you need "seq1" to have a string and you can't use == that way. Also, since both FS and OFS default to a space, your BEGIN block isn't needed. Putting all that together, this command, which is the same idea you were trying, should work as expected:

$ awk '($4 ~ /^NZ_JAHWGH/){$3="seq1"} ($4 ~ /^NZ_CAJGBF/){$3="seq2"}1' file.txt
chr - seq1 NZ_JAHWGH010000010.1 0 60562 green_a4
chr - seq1 NZ_JAHWGH010000012.1 0 466573 green_a4
chr - seq1 NZ_JAHWGH010000013.1 0 125526 green_a4
chr - seq1 NZ_JAHWGH010000014.1 0 717625 green_a4
chr - seq1 NZ_JAHWGH010000015.1 0 209757 green_a4
chr - seq1 NZ_JAHWGH010000016.1 0 55318 green_a4
chr - seq1 NZ_JAHWGH010000017.1 0 467034 green_a4
chr - seq2 NZ_CAJGBF010000017.1 0 83173 green_a4
chr - seq2 NZ_CAJGBF010000018.1 0 76510 green_a4
chr - seq2 NZ_CAJGBF010000019.1 0 67820 green_a4
chr - seq2 NZ_CAJGBF010000021.1 0 61770 green_a4
chr - seq2 NZ_CAJGBF010000022.1 0 56876 green_a4
chr - seq2 NZ_CAJGBF010000023.1 0 50411 green_a4
chr - seq2 NZ_CAJGBF010000024.1 0 49535 green_a4
0
2

How about sed?

sed -e "s/seq.* NZ_JAHWGH/seq1 NZ_JAHWGH/" -e "s/seq.* NZ_CAJGBF/seq2 NZ_CAJGBF/" file.txt
3
  • Thanks, its working, or is there any way to change like using range such as seq1: seq9 replace with seq1 and seq50: seq57 replace as seq2.
    – umar
    Mar 11 at 16:27
  • 1
    @umar that is a completely different question, please post it separately.
    – terdon
    Mar 11 at 16:49
  • ok, i will do that
    – umar
    Mar 11 at 16:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .