awk to echo até se o loop for bem sucedido após a correspondência do padrão

0

Eu tenho um arquivo

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

Agora na fila inteira quando eu encontrar "R" & & então "O" ou "S" eu quero obter a coluna não e com base na coluna não, eu preciso executar um comando e se for verdade, em seguida, exibir L em vez de R e O ou S se for false então F em vez de R e F em vez de O (para todos os O's consecutivos) ou S

agora da coluna não, eu determinarei a data,

digamos que a primeira linha R está em 5, então a data será a coluna não-3, ou seja, 2º,

para a data da segunda linha será 6-3, ou seja, 3ª, 3ª linha novamente 5-3, ou seja, 2º,

Então eu vou estar usando uma data variável =% m / d (da coluna não-3) /% Y

agora o comando é ./bpimagelist -client <column 1> -policy <column 2> -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l , agora se o valor for 0 então é falso se for gt 0 então é verdade.

XYZ is false
PQR is true
ABC is true

então a saída deve ser

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

De acordo com Valentin, depois de fazer algumas alterações, este é o código que parece funcionar bem.

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

No entanto, uma pequena consulta é que ela deve realizar essas alterações apenas quando R é seguido por O e até encontrar qualquer coisa, exceto O.

, o que significa que não deve realizar nenhuma alteração se o arquivo de entrada for

XYZ 123 S S R O O O O

, o que significa que R é continuado apenas por O, então não há necessidade de realizar nenhuma alteração, senão, qualquer coisa diferente de O é encontrada, execute as alterações

    
por Sid 25.04.2017 / 15:52

1 resposta

0

Tentarei responder a sua solicitação passo a passo. Apenas assuma aqui que input é uma linha do seu arquivo de entrada:

Extraindo o número da coluna do primeiro caractere "R"

Este é um trabalho bastante simples para awk :

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

Considerando como você está computando sua data, estou assumindo que o 'R' não pode estar na primeira linha (caso contrário, o número do dia poderia ser 0).

Extraindo valores da 1ª e 2ª coluna

Isso é ainda mais simples:

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

Construindo saída

No caso de o comando retornar True :

sed 's/ R / L /' < input

No caso de o comando retornar 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

Colocando tudo junto

Embora isso seja desaprovado, não vejo como evitar loops em suas linhas de entrada, já que você precisa executar um comando muito específico para cada linha. Esteja ciente de que, para arquivos grandes, isso pode me tornar super lento. Como o seu script pode parecer com todos esses elementos:

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
    
por 25.04.2017 / 18:08

Tags