próbuje zawierać wartości w moich danych, które mają:
- druga kolumna mniejsza niż 1;
i wykluczać wpisy z:
- pierwsza kolumna równa 3 i
- czwarta kolumna większa niż 25
- 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 № 1Na 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.