pessima condizione di vero e falso


9

Mi sono imbattuto che se lo usiamo awk 0 inputfile, non stamperà nulla perché 0significa falso della condizione.

Se usiamo awk 1 inputfile, stamperà tutto come 1vero per ogni riga interpretata da awk.

Se usiamo awk any_string inputfile, non stamperà nulla perché tutte le variabili awk inizializzate come zero quindi false.

Ma se lo utilizziamo awk any_integer inputfile, diventerà vero e stamperà ogni riga del file, posso sapere qual è il motivo?

Non riesco a trovare questo è stato spiegato nel manuale GNUawk però.


3
da any_integerI supporti numero letterale dire come 7, 89, ecc .. in caso affermativo, la ragione è un numero diverso da 0mezzi truecondizione
Sundeep

Risposte:


13

Vero per awk è una stringa non vuota o un numero diverso da zero (con numeri che sono numeri interi decimali o virgola mobile e con alcune implementazioni awk sono supportati anche esadecimali o ottali). Le cose racchiuse tra virgolette doppie sono stringhe, i numeri letterali non quotati sono numeri, ma per ogni altra cosa, ci sono regole complesse per determinare se qualcosa deve essere trattato come una stringa o un numero. Il awkmanuale GNU ha un intero capitolo su questo .

Vero:

  • awk '1' (numero diverso da zero)
  • awk '1e8' (numero diverso da zero)
  • awk '-0.01' (numero diverso da zero)
  • awk '"foo"' (stringa non vuota)
  • awk '"0"' (stringa non vuota)
  • awk '0 ""' (la concatenazione produce una stringa che qui non è vuota)
  • echo 0 | awk '$1 ""' (lo stesso per un campo $ n)
  • awk 'substr("000", 1, 1)'(il risultato di substr()è sempre una stringa)
  • echo '0foo' | awk '$0' ($ 0 è una stringa non numerica quindi è considerata una stringa (non vuota))

falso:

  • awk '0' (0 numero)
  • awk '""' (stringa vuota)
  • echo 0000e123 | awk '$1' ($ 1 è considerato un numero se è una stringa numerica che è qui ed è 0)
  • echo ' 0 ' | awk '$0' (gli spazi iniziali e finali vengono ignorati per determinare se una stringa è numerica).
  • awk '" 2foo" - 2' (una stringa coinvolta in un'espressione aritmetica viene convertita in un numero con qualsiasi cosa oltre il numero ignorato)
  • awk 'unset_or_empty_variable' (stringa vuota)
  • awk '"non-numerical-string" + 0'

YMMV:

  • awk '1e-500' (alcuni si lamenteranno, altri lo tratteranno come 0)
  • awk '"0x1" + 0'(non tutte le implementazioni awk supportano esadecimali, su quelle che lo fanno "0x1"vengono convertite in 1, in altre in 0. Alcune versioni della specifica POSIX richiedono inavvertitamente implementazioni per supportare quel numero esadecimale lì ed è stato ritirato in seguito. gawkRiconosce ancora quel numero esadecimale quando POSIXLY_CORRECTè in l'ambiente)
  • awk '010 - 8' (stesso (non proprio come lo 010 è letterale qui invece di convertito da una stringa) per ottali)
  • awk '0x1 - 1'(su awkimplementazioni che non supportano numeri esadecimali, 0x1è la concatenazione di 0e la x1variabile che produce "0"che viene convertita in un numero (0), se si sottrae 1si ottiene -1un numero diverso da zero).

Ciò significa che se si desidera verificare se una stringa non è vuota, non è necessario:

awk '$ 1 {print $ 1, "non è vuoto"}'

Ma

awk '$1 != "" {print $1, "is not empty"}'

Altrimenti non direbbe 0o -0000E+00001234non è vuoto.


Risposta impressionante e dettagliata! Una domanda però: nell'esempio finale che hai dato, ho provato la sintassi e la prima funziona, dove salta $ 1 che è vuoto e stampa solo quella riga con $ 1 non vuota, perché se $ 1 è una stringa vuota sarà Falso, e quindi non stampa l'output, vero?
sylye,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.