2.1 The eval Command & Core Evaluation Functions

Key Takeaways

  • The eval command evaluates mathematical, string, comparison, conditional, and null-handling expressions per event at search time, writing results to a new or existing field without modifying _raw.
  • String manipulation functions like len(), substr(), lower(), upper(), and replace() allow granular parsing and normalization, with substr() utilizing 1-based indexing.
  • Comparison and conditional functions (if(), case(), validate()) enable dynamic branching logic, where case() evaluates pairs sequentially and validate() returns an error string on the first false condition.
  • Mathematical functions such as round(X, [Y]), ceil(X), and floor(X) control numeric precision and rounding behavior, while arithmetic operations handle null values by returning null.
  • Null handling functions (isnull(), isnotnull(), coalesce()) detect missing values and perform fallback selection across alternative fields for log schema normalization.
Last updated: August 2026

2.1 The eval Command & Core Evaluation Functions

Quick Answer: The eval command calculates an expression for every incoming event and assigns the resulting value to a destination field at search time. It operates as a streaming command in memory, leaving raw indexed data (_raw) untouched. The eval command supports mathematical operators, string functions (len, substr, lower, upper, replace), conditional branching (if, case, validate), numeric rounding (round, ceil, floor), and null resolution (coalesce, isnull, isnotnull). String literals require double quotes ("..."), field names are unquoted and strictly case-sensitive, and the dot (.) is Splunk's dedicated concatenation operator. Note that + is the documented exception among arithmetic operators: it adds two numbers or concatenates two strings.


1. Architectural Foundations of the eval Command

In the Splunk search processing pipeline, the eval command serves as the primary mechanism for row-level data transformation, dynamic metric calculation, conditional classification, and field normalization. Mastering eval syntax, quoting semantics, and built-in functions is one of the most heavily tested areas on the Splunk Core Certified Power User examination.

+-----------------------+      +-------------------------------+      +-------------------------+
| Incoming Event Stream | ---> | eval dest_field = <expression>| ---> | Transformed Stream      |
| bytes=1048576, ms=450 |      | (e.g., MB = bytes/1024/1024)  |      | bytes, ms, MB=1.00      |
+-----------------------+      +-------------------------------+      +-------------------------+

Core Operational Characteristics:

  1. Event-Level Streaming Execution: eval is a streaming command. It evaluates expressions on an event-by-event basis as records pass through the search head memory pipeline without requiring historical buffering or global sorting.
  2. Search-Time Immutability: eval never modifies the underlying immutable data stored on indexers (_raw or TSIDX index files). All calculated fields exist exclusively in memory for the duration of the search lifecycle.
  3. Destination Field Behavior: If the specified destination field already exists in an event, eval overwrites its value with the result of the expression. If the destination field does not exist, eval dynamically creates it and appends it to the event's field list.
  4. Sequential Expression Chaining: You can define multiple field assignments within a single eval command by separating assignments with commas. Splunk processes chained assignments sequentially from left to right, allowing downstream expressions to immediately reference fields calculated earlier in the same statement.
`-- Sequential evaluation chaining: latency_sec is calculated first, then consumed by latency_tier`
... | eval latency_sec = response_time_ms / 1000, 
           latency_tier = if(latency_sec < 1.0, "OPTIMAL", "DEGRADED")

Strict Quoting Rules in eval Expressions

Understanding how Splunk's SPL parser distinguishes between literals, field references, and special identifiers is vital for writing error-free queries:

Token TypeSyntax RuleExample SPLParsing Interpretation
String LiteralsMust be enclosed in double quotes ("...")eval env = "Production"The static string text "Production" is assigned to env.
Field ReferencesMust be unquotedeval total_kb = bytes / 1024Reads the current value of the field bytes from each event.
Special Field NamesMust be enclosed in single quotes ('...')eval load = 'cpu-usage%' * 1.2Allows field names containing hyphens, spaces, periods, or symbols.
Numeric ConstantsMust be unquotedeval rate = 0.0825Interpreted directly as an integer or floating-point number.

[!WARNING] Critical Exam Trap: If you execute | eval environment = production without double quotes around production, Splunk interprets production as a field name. If no field named production exists in the event, the new field environment evaluates to null. To assign a literal string, you must write | eval environment = "production".


2. Core String Manipulation Functions

Splunk provides a comprehensive suite of string functions designed to extract sub-elements, calculate lengths, standardize casing, and perform regex substitutions.

                         STRING MANIPULATION IN EVAL
                                     │
         ┌───────────────────────────┼───────────────────────────┐
         ▼                           ▼                           ▼
   Length & Slicing           Casing & Cleanup           Pattern Replacement
   • len(str)                 • lower(str)               • replace(str, regex, sub)
   • substr(str, start, len)  • upper(str)               • trim(str, [chars])

len(X)

Returns the integer character count of string field X. If X is non-existent or null, len() returns null.

... | eval password_length = len(user_password)

substr(X, Y, [Z])

Extracts a substring from string X starting at character position Y (using 1-based indexing) for an optional character length Z. If Z is omitted, substr() extracts all remaining characters through the end of the string. Negative values for Y indicate an offset starting from the end of the string.

`-- Extract first 3 characters (area code) from phone number`
... | eval area_code = substr(phone_number, 1, 3)

`-- Extract the last 4 characters of an account number`
... | eval account_suffix = substr(account_id, -4)

[!IMPORTANT] 1-Based Indexing Rule: Unlike languages like C, Java, or Python which use 0-based indexing, Splunk's substr() function is 1-based. In substr("Splunk", 1, 2), index 1 corresponds to "S", yielding "Sp".

lower(X) and upper(X)

Converts all alphabetic characters in string X to lowercase or uppercase, respectively. These functions are critical for normalizing divergent field values before executing group-by aggregations or case-sensitive comparisons.

... | eval normalized_user = lower(username), alert_status = upper(raw_status)

replace(X, Y, Z)

Scans string X for substrings matching the regular expression Y and replaces all matches with the replacement string Z. Capture groups (e.g., \1, \2) can be referenced within Z.

`-- Strip domain suffix from fully qualified hostnames`
... | eval short_host = replace(host, "\.corp\.example\.com$", "")

`-- Mask middle 6 digits of a 10-digit credit card string`
... | eval masked_card = replace(cc_num, "^(\d{4})\d{6}(\d{4})$", "\1******\2")

trim(X, [Y]), ltrim(X, [Y]), and rtrim(X, [Y])

Strips leading and trailing characters from string X. If the optional character set Y is omitted, it defaults to stripping whitespace characters (spaces, tabs, newlines).

`-- Strip leading and trailing slashes from URI paths`
... | eval clean_uri = trim(uri_path, "/")

String Concatenation: Dot (.) vs. Plus (+)

Splunk's operator table lists . as the concatenation operator, and the dot is what every official example uses. Write it that way:

`-- Canonical SPL concatenation`
... | eval full_endpoint = protocol . "://" . host . ":" . port . uri_path

Be careful with the widely repeated myth that + "returns null on strings." Splunk's own documentation says the opposite: "with the exception of addition, arithmetic operations might not produce valid results if the values are not numerical," and "when concatenating values, Splunk software reads the values as strings, regardless of the value." In practice + concatenates whenever its operands are not numeric:

`-- This does NOT return null. It concatenates: "Jane Doe"`
... | eval full_endpoint = firstName + " " + lastName

The real hazard runs the other direction: + silently switches meaning based on the data. If both operands look numeric, "0001" + "0002" adds to 3; if they do not, it concatenates to 00010002. Use . when you mean concatenation and tonumber() when you mean arithmetic, so the intent never depends on the data.


3. Comparison and Multi-Branch Conditional Functions

Conditional evaluation allows power users to build dynamic categorization tags, assign severity levels, and implement business routing rules directly within the pipeline.

+-----------------------------------------------------------------------------------------+
|                        CONDITIONAL BRANCHING LOGIC IN EVAL                              |
+-----------------------------------------------------------------------------------------+
| if(predicate, true_val, false_val)  --> Single binary condition (if-then-else)          |
+-----------------------------------------------------------------------------------------+
| case(c1, v1, c2, v2, ..., true(), def) --> Sequential multi-branch rule evaluation      |
+-----------------------------------------------------------------------------------------+
| validate(c1, e1, c2, e2, ...)       --> Data validation (returns error of FIRST failure)|
+-----------------------------------------------------------------------------------------+

if(predicate, true_value, false_value)

Evaluates a single boolean condition (predicate). If the condition evaluates to true, if() returns true_value; otherwise, it returns false_value.

... | eval http_category = if(status >= 400, "ERROR", "SUCCESS")

case(condition1, value1, condition2, value2, ..., [true(), default_value])

Evaluates multiple condition-value pairs sequentially from left to right. It returns the value associated with the first condition that evaluates to true and immediately halts evaluation (short-circuiting). If no conditions evaluate to true and no default condition is provided, case() returns null.

... | eval risk_score = case(
    status == 500 OR status == 503, "CRITICAL",
    status == 401 OR status == 403, "HIGH",
    status == 404, "MEDIUM",
    status == 200, "LOW",
    true(), "UNKNOWN"
)

[!TIP] Power User Best Practice: Always terminate case() statements with true(), "<default_value>" (or 1==1, "<default_value>") as the final fallback pair. This ensures that unhandled edge cases or unexpected log values are explicitly classified rather than silently becoming null.

validate(condition1, error1, condition2, error2, ...)

Designed specifically for data hygiene and schema validation. It evaluates conditions sequentially and returns the error string associated with the first condition that evaluates to FALSE. If all conditions evaluate to true, validate() returns null.

`-- Identifies why an event failed data formatting standards`
... | eval data_error = validate(
    isnotnull(clientip), "Missing Client IP",
    isnum(status), "Status is non-numeric",
    status >= 100 AND status <= 599, "Status code out of HTTP range"
)
| where isnotnull(data_error)

match(X, Y) and like(X, Y)

  • match(string, regex): Returns boolean true (1) if the regular expression Y matches string X; otherwise false (0).
  • like(string, pattern): Evaluates SQL-style wildcard patterns where % matches any number of characters and _ matches a single character.
... | eval is_admin = if(match(user, "(?i)^admin_"), "YES", "NO"),
           is_corp_ip = if(like(clientip, "10.200.%.%"), 1, 0)

4. Mathematical and Numeric Evaluation Functions

Splunk provides built-in numeric functions to handle rounding, precision adjustments, and mathematical transformations:

FunctionSignatureOperational DescriptionInput ExampleOutput
round(X, [Y])round(num, [decimals])Rounds X to Y decimal places (defaults to integer 0 decimals if Y is omitted).round(3.14159, 2)<br>round(8.75)3.14<br>9
ceil(X)ceil(num)Ceiling: returns the smallest integer greater than or equal to X.ceil(4.12)<br>ceil(-2.8)5<br>-2
floor(X)floor(num)Floor: returns the largest integer less than or equal to X.floor(4.89)<br>floor(-2.1)4<br>-3
abs(X)abs(num)Returns the absolute value of numeric expression X.abs(-45.2)45.2
min(X, Y, ...)min(n1, n2, ...)Returns the minimum numeric value among all argument expressions.min(12, 5, 29)5
max(X, Y, ...)max(n1, n2, ...)Returns the maximum numeric value among all argument expressions.max(12, 5, 29)29
pow(X, Y)pow(base, exp)Computes X raised to the power of Y ($X^Y$).pow(2, 8)256
sqrt(X)sqrt(num)Returns the square root of non-negative number X.sqrt(144)12

Handling Numeric Edge Cases & Division by Zero

  • Division by Zero: When an arithmetic expression encounters division by zero (e.g., eval ratio = total / count where count = 0), Splunk does not throw a search error. The target field evaluates cleanly to null.
  • Non-Numeric Arithmetic: Attempting arithmetic operations on fields containing non-numeric strings results in null.

5. Null Identification and Normalization Functions

In enterprise environments, logs from disparate systems frequently record identical attributes under different field names, or omit fields entirely.

+-----------------------------------------------------------------------------------------+
|                        NULL RESOLUTION WITH COALESCE                                    |
+-----------------------------------------------------------------------------------------+
| Heterogeneous Sources:                                                                  |
|   Source A (Windows): Account_Name = "jsmith"  |  src_user = null  |  username = null   |
|   Source B (Linux):   Account_Name = null      |  src_user = null  |  username = "root" |
|                                                                                         |
| SPL Transformation:                                                                     |
|   | eval user_id = coalesce(Account_Name, username, src_user, "UNKNOWN")                |
|                                                                                         |
| Result:                                                                                 |
|   Source A -> user_id = "jsmith"                                                        |
|   Source B -> user_id = "root"                                                          |
+-----------------------------------------------------------------------------------------+

isnull(X) and isnotnull(X)

  • isnull(X): Returns boolean true (1) if field X does not exist in the event or contains a null value; otherwise false (0).
  • isnotnull(X): Returns boolean true (1) if field X exists and contains a non-null value; otherwise false (0).
... | eval ip_status = if(isnull(client_ip), "UNRESOLVED", "RESOLVED")

coalesce(field1, field2, field3, ...)

Evaluates the arguments in order from left to right and returns the value of the first non-null argument. If all provided arguments evaluate to null, coalesce() returns null.

`-- Normalize heterogeneous IP field names across firewall, proxy, and web logs`
... | eval canonical_ip = coalesce(src_ip, clientip, c_ip, remote_addr, "0.0.0.0")

null()

Returns a null value. This function is typically used in conditional branches to explicitly discard or undefine a field under specific conditions.

`-- Strip internal test IPs from downstream analytics`
... | eval public_ip = if(like(clientip, "10.%"), null(), clientip)

6. Comprehensive eval Function Reference

The following reference matrix summarizes the core functions tested on the Power User exam:

Function SignatureCategoryPurpose & DescriptionSPL ExampleOutput
len(X)StringReturns integer length of string Xlen("Splunk")6
substr(X, Y, [Z])StringSubstring starting at 1-based index Y for length Zsubstr("Enterprise", 1, 5)"Enter"
lower(X)StringConverts string X to lowercaselower("Admin")"admin"
upper(X)StringConverts string X to uppercaseupper("warn")"WARN"
replace(X, Y, Z)StringRegex replacement of pattern Y in X with Zreplace("v1.2.3", "^v", "")"1.2.3"
trim(X, [Y])StringStrips whitespace/characters from ends of Xtrim(" test ")"test"
if(C, T, F)ConditionalEvaluates boolean C; returns T if true, F if falseif(status==200, 1, 0)1 or 0
case(C1,V1,...)ConditionalMulti-branch evaluation; returns first true valuecase(code==0, "OK", true(), "ERR")"OK" or "ERR"
validate(C1,E1,...)ConditionalReturns error string of first FALSE conditionvalidate(port>0, "Invalid Port")null or "Invalid Port"
round(X, [Y])MathematicalRounds X to Y decimals (default 0)round(45.678, 2)45.68
ceil(X)MathematicalSmallest integer greater than or equal to Xceil(3.01)4
floor(X)MathematicalLargest integer less than or equal to Xfloor(3.99)3
abs(X)MathematicalAbsolute value of numeric expression Xabs(-105)105
isnull(X)Null LogicReturns true (1) if X is nullisnull(user_session)1 or 0
isnotnull(X)Null LogicReturns true (1) if X is non-nullisnotnull(host)1 or 0
coalesce(A, B, ...)Null LogicReturns value of first non-null argumentcoalesce(src, client, "N/A")Value or "N/A"

7. Complex Nested Expressions in Production SPL

In real-world enterprise searches, power users combine multiple eval functions into nested expressions to perform comprehensive data sanitization and categorization in a single pipeline stage:

index=web sourcetype=access_combined
| eval canonical_user = lower(trim(coalesce(user, auth_user, account, "anonymous"))),
       response_sec = round(response_time_ms / 1000, 3),
       status_tier = case(
           status >= 500, "5xx_SERVER_ERROR",
           status >= 400, "4xx_CLIENT_ERROR",
           status >= 300, "3xx_REDIRECT",
           status >= 200, "2xx_SUCCESS",
           true(), "OTHER_STATUS"
       ),
       is_slow = if(response_sec > 2.500 AND status_tier != "2xx_SUCCESS", 1, 0)
| stats count, avg(response_sec) as mean_latency by status_tier, is_slow

Explanation of Execution:

  1. canonical_user resolves the first non-null username across three field variations, strips surrounding whitespace, and converts the string to lowercase.
  2. response_sec converts millisecond timings into decimal seconds, rounded cleanly to 3 decimal places.
  3. status_tier classifies the event based on HTTP response ranges using sequential case() evaluation with a catch-all true() condition.
  4. is_slow flags requests taking longer than 2.5 seconds that also resulted in errors.

8. Common Exam Traps & Pitfalls

  • Case Sensitivity in Field Names: Field names within eval expressions are strictly case-sensitive, and Splunk documents that the entire eval expression is case-sensitive. eval x = Status + 1 will not read the field status. Write commands and functions in lowercase, as Splunk's documentation does throughout.
  • Unquoted Literal Assignment: Writing | eval role = admin assigns the value of the field admin (often null), whereas | eval role = "admin" assigns the string literal "admin".
  • The + Ambiguity: | eval name = first_name + " " + last_name does not return null — Splunk treats addition as the one arithmetic operator that also concatenates strings, so it produces "Jane Doe". The trap is that + changes meaning when the operands happen to be numeric. Use the dedicated concatenation operator: | eval name = first_name . " " . last_name.
  • Missing Default in case(): If none of the conditions in a case() statement evaluate to true and no true(), "default" pair is provided, the destination field is assigned null.
Test Your Knowledge

A Splunk Power User needs to create a normalized field named user_tier. The requirement states: if account_level is null, use the value from default_level; if both are null, assign the string literal 'STANDARD'. Which eval expression correctly accomplishes this?

A
B
C
D
Test Your Knowledge

An analyst executes the following search pipeline on an event stream: ... | eval raw_cost = 42.871, rounded_cost = round(raw_cost, 1), ceil_cost = ceil(raw_cost), floor_cost = floor(raw_cost) What are the resulting values for rounded_cost, ceil_cost, and floor_cost?

A
B
C
D
Test Your Knowledge

What is the result of executing the SPL expression | eval full_name = firstName + " " + lastName when firstName="Jane" and lastName="Doe"?

A
B
C
D