3. Core text-processing toolkit for crash s
Crash CAE workflows generate enormous volumes of structured text: LS-DYNA keyword decks (*KEYWORD files), boundary-condition includes, material cards, and solver logs such as d3hsp, messag, and glstat. Before any automation script can make decisions, it must extract, filter, and reshape that text. The seven tools covered here — grep, sed, awk, cut, sort, uniq, and tr — form the backbone of that extraction layer. This section treats them not as isolated commands but as a coordinated pipeline for real deck and log data.
Choosing the right tool for the job
Each tool has a natural domain. grep selects lines by pattern; sed performs stream edits (substitution, deletion, insertion); awk is a field-aware record processor with arithmetic and control flow; cut extracts fixed columns or delimited fields; sort orders records; uniq collapses or counts adjacent duplicates; tr translates or deletes characters. The table below maps typical crash-CAE tasks to the primary tool.
| Task | Primary tool | Typical target |
|---|---|---|
Find all *MAT_ cards | grep | keyword deck |
| Rename a part ID across includes | sed | boundary-condition deck |
| Sum nodal kinetic energy per step | awk | glstat |
| Extract columns 1–10 of a fixed-width card | cut | keyword deck |
| Rank parts by mass | sort | mass report |
| Count duplicate node IDs | uniq -c | node list |
| Strip CR from Windows decks | tr -d '\r' | any deck |
grep: locating cards and log events
Keyword decks are line-oriented, and grep is the fastest way to inventory them. To list every material card with line numbers:
grep -n '^\*MAT_' model.k
grep -c '^\*PART' model.k
grep -rn '^\*INITIAL_VELOCITY' include/
The -n flag gives line numbers for later sed edits, -c counts matches, and -r recurses through an include directory. For solver logs, anchor patterns to avoid false hits: grep -E 'error|warning' messag catches both, while grep -i 'negative volume' d3hsp finds the classic element-inversion message regardless of case. Use -v to invert — for example, dropping comment lines (grep -v '^\$') before further processing.
sed: surgical edits on decks
sed rewrites text without opening an editor, which is essential when a script must patch hundreds of includes. A common task is updating a termination time in a control card:
sed -i 's/\(^\*CONTROL_TERMINATION\)/\1/' model.k
sed -i '/^\*CONTROL_TERMINATION/{n;s/^\(.\{10\}\)/\1/}' model.k
More practically, substitute a specific part ID only within a card block using an address range:
sed -i '/^\*PART/,/^\*END_PART/ s/^\(.\{8\}\) \{0,1\}12345/\1 67890/' model.k
For log cleanup, delete ANSI escape sequences and blank lines before parsing: sed -e 's/\x1b\[[0-9;]*m//g' -e '/^$/d' messag > messag.clean. Always test destructive edits with a dry run (omit -i) and diff the result.
awk: field-aware extraction and arithmetic
awk is the workhorse for tabular solver output. In glstat, energy lines look like kinetic energy = 1.234E+03. To sum kinetic energy across all steps:
awk '/kinetic energy/ {sum += $4} END {printf "total KE = %.3e\n", sum}' glstat
For fixed-width keyword cards, awk can slice by character position using substr. Extracting node IDs and coordinates from a *NODE block:
awk '/^\*NODE/{f=1;next} /^\*/{f=0} f {print substr($0,1,8), substr($0,9,16), substr($0,25,16), substr($0,41,16)}' model.k
This pattern — a flag set on a card header, cleared on the next header — is the standard idiom for parsing keyword blocks. Combine it with NF and NR to skip headers or report line numbers in diagnostics.
cut, sort, uniq, tr: shaping and deduplicating
cut handles simple column extraction when delimiters are consistent. For a comma-separated mass report: cut -d, -f1,3 mass.csv. For fixed-width decks, cut -c1-8,25-40 model.k pulls ID and coordinate fields. sort orders results — sort -k3 -n -r mass.txt ranks by numeric mass descending. uniq only collapses adjacent duplicates, so it must follow sort: sort node_ids.txt | uniq -c | sort -nr | head reveals the most frequently referenced node IDs, a quick check for over-constrained boundary conditions. tr normalizes characters: tr -d '\r' < win.k > unix.k fixes CRLF decks, and tr '[:lower:]' '[:upper:]' normalizes keyword case before matching.
Composing a pipeline: boundary-condition audit
The real power emerges when these tools chain together. Suppose you must verify that every node referenced in a *BOUNDARY_SPC_SET actually exists in the node list. First extract referenced IDs, then compare against defined IDs:
grep -A2 '^\*SET_NODE_LIST' model.k | awk 'NF>1 && $1 !~ /^\*/ {for(i=1;i<=NF;i++) print $i}' | sort -u > ref_ids.txt
awk '/^\*NODE/{f=1;next} /^\*/{f=0} f {print substr($0,1,8)}' model.k | tr -d ' ' | sort -u > def_ids.txt
comm -23 ref_ids.txt def_ids.txt
Any output from comm -23 is a referenced-but-undefined node — a deck error that would otherwise surface only as a solver termination. This pipeline is the template for most pre-solve validation scripts.
Practical notes and pitfalls
uniq without a preceding sort silently misses non-adjacent duplicates; sed -i on a symlinked include may break the link; awk field splitting on fixed-width cards fails when fields contain spaces — use substr instead of $1.
bin/ of reusable one-liners (e.g., deck_nodes, log_errors) so pipelines stay readable and testable. Validate each stage with wc -l and head before trusting downstream results.
Mastering these seven tools turns raw solver text into structured, verifiable data. The next step is embedding them inside shell scripts with proper quoting, exit-code checks, and error handling — the subject of the following section.