Replace 2nd column in file

I have following entries file abc.txt

abc83.out.remote           TRUE
abc84.out.remote           TRUE
abc85.out.remote           TRUE
abc86.out.remote           TRUE 

Please help me, how do i toggle the entries listed in 2nd column based on the search patterns (abcxx)

abcxx, i can get using for loop, my problem is to replace the corresponding 2nd column entries (TRUE/FALSE)
Creating a tmp file for this is not a problem. Also. 3 tab spaces after 1st column should be preserved after replacing TRUE with FALSE or vice versa.
Please help

I'm sure not sure what exactly you want to check in file: abc.txt Just to give you an idea, in below program I'm using awk to check if 1st column is abc83.out.remote if yes, then keep 2nd column as TRUE else change it to FALSE by preserving 3 tab spaces:-

awk '$1=="abc83.out.remote" { print $1"\t\t\tTRUE" } $1!="abc83.out.remote" { print $1"\t\t\tFALSE" } ' abc.txt

You can modify this code as per your requirement. I hope this helps.

1 Like

Thanks bipinajith
But, will it work, if original file has not 3 tab spaces.
otherway, if original file doesn't have 3 tab spaces, then how do i search and replace, because, above

awk 

will search for fixed pattern only.

to check if 1st column is abc83.out.remote if yes, then change the 2nd column to FALSE
there is no else case. if TRUE is found against abc83.out.remote , then change the second col to FALSE

You need read AWK user guide again, I don't see any parts in AWK and tell you

awk will search fixed pattern only.

Tried the below nawk and it worked, but still i have one issue pending
if i use "for" loop to get "abcxx" then it displays multiple entries.

nawk -v col=2 -v val="TRUE" -v valN="\t\t\tFALSE\t\t\t" '$col == val {$col = valN}1' /tmp/test

I think we have a language barrier. Your specification of what you want done is not clear.

You say you want to match abcxx, but none of your input lines contains the string "abcxx".

You say that you want to change the second column, but you say that there are three tab spaces (whatever that means) and that the tab spaces have to be preserved. If you mean that there are three tab characters between the 1st field and the field that contains TRUE and that you want each tab character to be treated as a field separator, then say that the tab character is your field separator and you want the 4th field set to TRUE if abcxx appears in field 1 and you want the 4th field set to FALSE if abcxx does not appear in field 1.

If by abcxx you mean that you want to match the string "abc" immediately followed by two decimal digits, then you need to match against "abc[0-9][0-9]"
instead of matching against "abcxx".

And, awk (nawk on Solaris systems) matches extended regular expressions, not just fixed strings.
----------------
And, I forgot to ask why you need a for loop to get the constant "abcxx"???

Ok let me try re-phrase.

i have file with following entries

% cat /tmp/test
TSCmerge77.Merge.out.remoteOn           TRUE                               write
TSCmerge78.Merge.out.remoteOn           TRUE                               write
TSCmerge79.Merge.out.remoteOn           TRUE                               write
TSCmerge80.Merge.out.remoteOn           TRUE                               write
TSCmerge100.Merge.out.remoteOn           TRUE                               write
TSCmerge101.Merge.out.remoteOn           TRUE                               write

When i try to get TSCmergexx list using "for" loop and try to match pattern, then i get the below output.

% for i in TSCmerge77 TSCmerge78 TSCmerge79 TSCmerge80 TSCmerge100 TSCmerge101; do cat /tmp/test |  nawk -v col1=1 -v colval="$i.Merge.out.remoteOn" -v col=2 -v val="TRUE" -v valN="\t\t\tFALSE\t\t\t" '$col1 == colval &&  $col == val {$col = valN}1'; done
TSCmerge77.Merge.out.remoteOn                   FALSE                    write
TSCmerge78.Merge.out.remoteOn           TRUE                               write
TSCmerge79.Merge.out.remoteOn           TRUE                               write
TSCmerge80.Merge.out.remoteOn           TRUE                               write
TSCmerge100.Merge.out.remoteOn           TRUE                               write
TSCmerge101.Merge.out.remoteOn           TRUE                               write
TSCmerge77.Merge.out.remoteOn           TRUE                               write
TSCmerge78.Merge.out.remoteOn                   FALSE                    write
TSCmerge79.Merge.out.remoteOn           TRUE                               write
TSCmerge80.Merge.out.remoteOn           TRUE                               write
TSCmerge100.Merge.out.remoteOn           TRUE                               write
TSCmerge101.Merge.out.remoteOn           TRUE                               write
TSCmerge77.Merge.out.remoteOn           TRUE                               write
TSCmerge78.Merge.out.remoteOn           TRUE                               write
TSCmerge79.Merge.out.remoteOn                   FALSE                    write
TSCmerge80.Merge.out.remoteOn           TRUE                               write
TSCmerge100.Merge.out.remoteOn           TRUE                               write
TSCmerge101.Merge.out.remoteOn           TRUE                               write
TSCmerge77.Merge.out.remoteOn           TRUE                               write
TSCmerge78.Merge.out.remoteOn           TRUE                               write
TSCmerge79.Merge.out.remoteOn           TRUE                               write
TSCmerge80.Merge.out.remoteOn                   FALSE                    write
TSCmerge100.Merge.out.remoteOn           TRUE                               write
TSCmerge101.Merge.out.remoteOn           TRUE                               write
TSCmerge77.Merge.out.remoteOn           TRUE                               write
TSCmerge78.Merge.out.remoteOn           TRUE                               write
TSCmerge79.Merge.out.remoteOn           TRUE                               write
TSCmerge80.Merge.out.remoteOn           TRUE                               write
TSCmerge100.Merge.out.remoteOn                  FALSE                    write
TSCmerge101.Merge.out.remoteOn           TRUE                               write
TSCmerge77.Merge.out.remoteOn           TRUE                               write
TSCmerge78.Merge.out.remoteOn           TRUE                               write
TSCmerge79.Merge.out.remoteOn           TRUE                               write
TSCmerge80.Merge.out.remoteOn           TRUE                               write
TSCmerge100.Merge.out.remoteOn           TRUE                               write
TSCmerge101.Merge.out.remoteOn                  FALSE                    write

whereas, i just want the lines that are "FALSE" not TRUE.

nawk ' { for(i=77;i<=101;i++) { if($1=="TSCmerge"i".Merge.out.remoteOn") { $2="\t\t\tFALSE\t\t\t"; print $0; } } } ' /tmp/test
1 Like

Thank you bipinajith, it is working :slight_smile:
i will modify it according to my need. Because file has other entries too.

See post http://www.unix.com/302738929-post7.html
Adapted to your new requirements, it would look like

awk 'BEGIN{OFS=FS="\t"}
     /TSCmerge(77|78|80)/ {$4=$4=="TRUE"?"FALSE":"TRUE"}
     1
    '  file
TSCmerge77.Merge.out.remoteOn            FALSE            write
TSCmerge78.Merge.out.remoteOn            FALSE            write
TSCmerge79.Merge.out.remoteOn            TRUE             write
TSCmerge80.Merge.out.remoteOn            FALSE            write
TSCmerge100.Merge.out.remoteOn           TRUE             write
TSCmerge101.Merge.out.remoteOn           TRUE             write
1 Like

RudiC, the link seems to be broken.

Sorry, repaired it in place.

1 Like

Its working now.

Given your sample input and your for loop, a trivial way to get what you want is:

sed -e 's/ *TRUE */                     FALSE                   /' /tmp/test

Note that there are three tab characters before and after the FALSE in the above substitution.

Note also that there are no tab characters in your input and the number of spaces in your input don't match what would be produced if the tabs had been converted to spaces, but this gives what you said you want given what you said is in your input file.

If you have a file that has a list of values you want to match in field 1 of your input lines in /tmp/test (in a file named keys in the following examples) one of the following examples may do what you want. They provide different ways of handling spacing around TRUE and FALSE, printing only matched lines or printing all lines, and changing or preserving existing spacing

#!/bin/ksh
echo "Use sed to change TRUE surrounded by spaces to 3 tabs FALSE 3 tabs"
sed -e 's/ *TRUE */                     FALSE                   /' /tmp/test
echo
echo "Use awk to change TRUE to FALSE on lines matching given keys and
print changed lines.  (Spaces and tabs are not changed.)"
awk 'FNR==NR{
        m[$1]
        next
}
substr($1, 1, index($1, ".") - 1) in m {
        sub(/TRUE/, "FALSE")
        print
}' keys /tmp/test
echo
echo "Use awk to change TRUE to FALSE on lines matching given keys and
print changed lines.  (Each set of spaces and tabs is changed to 3 tabs.)"
awk 'FNR==NR{
        m[$1]
        next
}
substr($1, 1, index($1, ".") - 1) in m {
        sub(/[ \t]*TRUE[ \t]*/, "\t\t\tFALSE\t\t\t")
        print
}' keys /tmp/test
echo
echo "Use awk to change TRUE to FALSE on lines matching given keys and
print all lines.  (Each set of spaces and tabs on lines that have been
changed is changed to 3 tabs.)"
awk 'FNR==NR{
        m[$1]
        next
}
substr($1, 1, index($1, ".") - 1) in m {
        sub(/[ \t]*TRUE[ \t]*/, "\t\t\tFALSE\t\t\t")
}
{       print
}' keys /tmp/test
echo
echo "Use awk to change TRUE to FALSE on lines matching given keys and
print all lines.  (Each set of paces and tabs is changed to 3 tabs.)"
awk 'FNR==NR{
        m[$1]
        next
}
{       if(substr($1, 1, index($1, ".") - 1) in m)
                sub(/[ \t]*TRUE[ \t]*/, "\t\t\tFALSE\t\t\t")
        else    sub(/[ \t]*TRUE[ \t]*/, "\t\t\tTRUE\t\t\t")
        print
}' keys /tmp/test

This was tested with the file keys containing the following three lines:

TSCmerge77
TSCmerge100
TSCmerge101

I used ksh in my tests, but any shell that supports basic Bourne shell syntax should work fine. This was tested on OS X. If you're using a Solaris system, use nawk or /usr/xpg4/bin/awk instead of awk.

1 Like

Perfect Don.. :slight_smile: thank you a lot.