/ / awk wyklucza wpisy, które nie spełniają wielu warunków, ale spełniają inne - linux, bash, if-statement, awk, warunek

awk wyklucza wpisy, które nie spełniają wielu warunków, ale spełniają inne - linux, bash, if-statement, awk, warunek

próbuje zawierać wartości w moich danych, które mają:

  1. druga kolumna mniejsza niż 1;

i wykluczać wpisy z:

  1. pierwsza kolumna równa 3 i
  2. czwarta kolumna większa niż 25
  3. czwarta kolumna mniejsza niż 35

Zasadniczo, wyłączając wpisy mieszczące się w przedziale od 25 do 35 dla kolumny 4 i 1 $ == 3. Czy można to zrobić w prosty sposób bez komplikowania?

Coś jak:

awk "{OFS="t"} {if (($2 < 1) & !($1==3 && $4>25 && $4<35)) print $0}" file.txt

Odpowiedzi:

2 dla odpowiedzi № 1

Na pierwszy rzut oka powinno to zrobić:

awk "BEGIN {OFS="t"} {if (($2 < 1) && !($1==3 && $4>25 && $4<35)) print $0}" file.txt

podobnie jak:

awk "BEGIN {OFS="t"} (($2 < 1) && !($1==3 && $4>25 && $4<35)) { print $0 }" file.txt

które mogłyby być dalej zredukowane do:

awk "BEGIN {OFS="t"} (($2 < 1) && !($1==3 && $4>25 && $4<35)) { print }" file.txt

lub:

awk "BEGIN {OFS="t"} (($2 < 1) && !($1==3 && $4>25 && $4<35))" file.txt

Podstawowymi zmianami jest użycie bloku BEGIN do ustawienia OFS raz i do użycia && połączyć ($1 < 1) warunek z warunkiem wykluczenia. Pojedynczy & jest operacją bitową i chociaż wartości dwóch terminów powinny wynosić 0 lub 1, a logika bitowa powinna działać, to z pewnością nie jest to normalny sposób, aby sobie z tym poradzić.

Właściwie, ponieważ po prostu drukujesz rekord wejściowy bez zmian, możesz nawet stracić BEGIN blokuj i używaj:

awk "(($2 < 1) && !($1==3 && $4>25 && $4<35))" file.txt

Jeśli wejście ma zakładki oddzielające pola, będą one obecne na wyjściu.

Wszystkie te skrypty pobierają dokładnie to, co powiedziałeś na liście wypunktowanej, ale twój tekst mówi „wyłączając wpisy mieszczące się w przedziale od 25 do 35 dla kolumny 4” i często bywa interpretowane jako odrzucanie wartości 25 i 35 (a także 26,34), ale nie jest to, co mówi lista wypunktowań ani implementuje kod. Poprawka jest oczywiście trywialna>= i <= zamiast > i <).

Nie dostarczyłeś żadnych danych testowych i oczekiwanych danych wyjściowych - staraj się to zrobić. Oto prosty generator danych kodu testowego (dający 54 linie wyjścia)

for h in 2 3 4
do
for i in -1 0 1
do
for j in 24 25 26 34 35 36
do
printf "%st%st%st%sn" $h $i blather $j
done
done
done

Po uruchomieniu i wyświetleniu danych wyjściowych do skryptu, wyjście to:

2       -1      blather 24
2       -1      blather 25
2       -1      blather 26
2       -1      blather 34
2       -1      blather 35
2       -1      blather 36
2       0       blather 24
2       0       blather 25
2       0       blather 26
2       0       blather 34
2       0       blather 35
2       0       blather 36
3       -1      blather 24
3       -1      blather 25
3       -1      blather 35
3       -1      blather 36
3       0       blather 24
3       0       blather 25
3       0       blather 35
3       0       blather 36
4       -1      blather 24
4       -1      blather 25
4       -1      blather 26
4       -1      blather 34
4       -1      blather 35
4       -1      blather 36
4       0       blather 24
4       0       blather 25
4       0       blather 26
4       0       blather 34
4       0       blather 35
4       0       blather 36

To wydaje się poprawne.