0

I have a file

XYZ 123 S S R O O S F
PQR 456 F S S R O F F
ABC 789 F S R S S F S

Now in entire row when I find "R" && then "O" or "S" I want to get the column no and based on the column no I need to perform a command and if it's true then display L instead of R and O or S if false then F instead of R and F instead of O(for all consecutive O's) or S

now from the column no I will determine date,

let say for 1st row R is on 5 so the date will be column no - 3 i.e 2nd,

for 2nd row date will be 6-3 i.e 3rd, 3rd row again 5-3 i.e 2nd,

So i will be using a variable date=%m/d(from column no-3)/%Y

now the command is ./bpimagelist -client <column 1> -policy <column 2> -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l, now if the value is 0 then it's false if it's gt 0 then it's true.

XYZ is false
PQR is true
ABC is true

then the ouput should be

XYZ 123 S S F F F S F
PQR 456 F S S L O F F
ABC 789 F S L S S F S

As per Valentin, after making few changes this is the code which seems to work fine.

while read line;
do
    day="$(echo $line | awk '{for (i=1; i<=NF; i++) { if($i == "R") { print i - 2; exit} } }')"
    if [[ ${#day} -lt 2 ]]; then day="0${day}"; fi
    month=`date '+%m'`
    year=`date '+%Y'`
    date=`echo $month/$day/$year`
    result=$(sudo /usr/openv/netbackup/bin/admincmd/bpimagelist -client "$(echo $line | awk '{print $1}')" -policy "$(echo $line | awk '{print $2}')" -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l)
    if [[ $result -ne 0 ]];
    then
        echo $line | sed 's/ R / L /'
    else
        echo $line | awk '{
                            afterR=0;
                            for (i=1; i<=NF; i++){
                              if ($i == "R") {
                                $i = "F";
                                afterR=1;
                              }
                              if (afterR == 1 && $i == "O") {
                                $i = "F"
                              }
                            }
                            print $0
                          }'
    fi
done < temp

However one small query is that it should perform these changes only when R is followed by O and until it finds anything but O.

meaning it shouldn't perform any changes if the input file is like

XYZ 123 S S R O O O O

which means R is continued by only O so no need to perform any changes, else anything other than O is found perform the changes

  • I need to perform a command and if it's true - what command? – RomanPerekhrest Apr 25 '17 at 13:55
  • 1
    I suggest you specify your question further, using broad phrases and approximations in your question does not allow a clear answer. I understand you are probably eager to get a solution but often times taking the time to carefully explain what it is you want to do is worth it. If you realise you cannot explain your problem here, then it probably is too specific. – Valentin B. Apr 25 '17 at 14:23
  • @ValentinB. Point taken, will keep it in mind I thought it will complicate things more so didn't want to explain too much but I understand we need to understand things completely to suggest something. – Sid Apr 25 '17 at 15:26
  • @RomanPerekhrest I explained it, let me know if you need further explanation, simplty it's a if loop on value calculated by bpimagelist command. – Sid Apr 25 '17 at 15:27
  • See stackoverflow.com/questions/1960895/… for how to get the output of a command into an awk variable. What else do you need to know to accomplish this? – Barmar Apr 25 '17 at 15:45
0

I will try to answer your request step by step. Just assume here that input is a line of your input file:

Extracting column number of the first "R" character

This is a pretty straightforward job for awk:

 awk '{for (i=1; i<=NF; i++) { if($i == "R") { print i - 3; exit} } }' < input

Considering how your are computing your date, I am assuming the 'R' cannot be on the first row (otherwise the day number could be 0).

Extracting values of 1st and 2nd column

This is even simpler:

awk '{print $1}' < input    # for first column
awk '{print $2}' < input    # for second column

Constructing output

In case command returns True:

sed 's/ R / L /' < input

In case command returns False:

awk '{
       afterR=0;
       for (i=1; i<=NF; i++){
         if ($i == "R") {
           $i = "F";
           afterR=1;
         }
         if (afterR == 1 && $i == "O") {
           $i = "F"
         }
       }
       print $0
     }' < input

Putting it all together

Although this is frowned upon, I see no way to avoid looping over your input lines, since you need to run a very specific command for each line. Be aware that for large files this might me super slow. How your script could look like with all these elements:

while read line;
do
    date="%m/d$(echo $line | awk '{for (i=1; i<=NF; i++) { if($i == "R") { print i - 3; exit} } }')/%Y"
    result=$(./bpimagelist -client "$(echo $line | awk '{print $1}')" -policy "$(echo $line | awk '{print $2}')" -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l)
    if [[ $result -ne 0 ]];
    then
        echo $line | sed 's/ R / L /'
    else
        echo $line | awk '{
                            afterR=0;
                            for (i=1; i<=NF; i++){
                              if ($i == "R") {
                                $i = "F";
                                afterR=1;
                              }
                              if (afterR == 1 && $i == "O") {
                                $i = "F"
                              }
                            }
                            print $0
                          }'
    fi
done < myinputfile.txt
  • I will go through it and let you know how it goes, a good point that R could be at the 1st row as well so I will have to find a way to calculate day no, it can't be just subtracting 3. – Sid Apr 26 '17 at 10:22
  • can the awk for false be converted into 1 line or it has to be like this only? – Sid Apr 26 '17 at 10:26
  • @Sid you can cram it into a single line, it just won't be very nice to read... – Valentin B. Apr 26 '17 at 15:42
  • I have edited the question, one small query is that it should perform these changes only when R is followed by O and until it finds anything but O. meaning it shouldn't perform any changes if the input file is like XYZ 123 S S R O O O O which means R is continued by only O so no need to perform any changes, else anything other than O is found perform the changes – Sid May 1 '17 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.