Skip to content

Instantly share code, notes, and snippets.

@dblume
Last active November 30, 2025 01:29
Show Gist options
  • Select an option

  • Save dblume/51d36f5656ecbb03012c604e4156ecd6 to your computer and use it in GitHub Desktop.

Select an option

Save dblume/51d36f5656ecbb03012c604e4156ecd6 to your computer and use it in GitHub Desktop.
Shell script to test regex for identifying paths to files esp with linenumbers
#!/usr/bin/env bash
#
# This is for a tmux shortcut to search terminal output for file paths.
#
# Original Regex from https://jyn.dev/how-i-use-my-terminal/
# See this gist: https://gist.github.com/dblume/51d36f5656ecbb03012c604e4156ecd6
#
# Note for macOS users: if you get no matches, the (\\>|$) at the end may be the
# problem. (Perhaps a BSD vs GNU issue.) Try removing it.
# Downside is product.price will match product.pric because no '\\>' to match.
test_pass () {
o=$(echo "$1" | grep -Eo "$path_regex") && echo "PASS:" "$o" || echo "FAIL"
}
test_fail () {
o=$(echo "$1" | grep -Eo "$path_regex") && echo "FAIL:" "$o" || echo "PASS: (no match)"
}
component='[[:alnum:]_\.#$%&+=@-]'
component_space='[[:alnum:] _\.#$%&+=@-]'
intermediate_paths="(/$component+)"
intermediate_paths_space="(/$component_space+)"
line_no=':[0-9]{1,10}'
# <------------------------------------------------------------must end with line no -----------------------------------------------------> <-------------------------------------------------------- doesn't need line no --------------------------------------------->< opt line >< opt col >< end >
# <--- quoted basename with optional dirs -----------> <-- optional basename with dirs ----> <------ basename with a-z -------> <----------------------- basename optional dir with req ext ----------------------> <- two or more dirs doesn't need ext ->
path_regex=$(echo "((\"($component_space+|~)?$intermediate_paths_space*\"|(($component+|~)?$intermediate_paths+|$component*[[:alpha:]]$component*))($line_no)|(($component*[[:alpha:]]$component*|~|\.|\.\.)$intermediate_paths?\.[[:alnum:]]{1,4}|($component+|~)?$intermediate_paths{2,})($line_no)?)($line_no)?(\\>|$)")
echo $path_regex
test_pass "words basepath_suffix_lines.py:42 here"
test_pass "words basepath_nosuffix_lines:42 here"
test_pass "basepath_suffix_lines.py:42 here"
test_pass "basepath_nosuffix_lines:42 here"
test_pass "words ~/path/tilde_path_file_with_suffix_lines_and_cols.tsx:42:15"
test_pass "~/path/tilde_path_file_with_suffix_lines_and_cols.tsx:42:15"
test_pass "words ~/path/path2/tilde_paths_file_with_suffix_lines_and_cols.tsx:42:15"
test_pass "words ~/path/tilde_path_file_with_suffix_no_lines.tsx"
test_pass "words ../path/parentdir_path_file_with_suffix_no_lines.tsx"
test_pass "words /path/slash_path_file_with_suffix_lines_and_cols.tsx:42:15"
test_pass "words /path/slash_path_file_with_suffix_no_lines.tsx"
test_pass "words path1/path2/path1_path2_file_with_suffix_no_lines.tsx"
test_pass "words \"quoted basepath with spaces suffix quoted_lines.py\":42 here"
test_pass "words \"quoted path with spaces/basepath with spaces suffix quoted_lines.py\":42 here"
test_pass "words \"~/quoted tilde basepath with spaces suffix lines.py\":42 here"
test_pass "words \"~/quoted path with spaces/tilde basepath with spaces suffix lines.py\":42 here"
test_pass "words \"../quoted path with spaces/parent path with spaces suffix lines.py\":42 here"
test_pass " File \"/home/dblume/path/filename_in_quotes_suffix_lines.py\":68, in price"
test_pass "Prefer no match expected but accept just match path ends/with/nonnumber.txt:10a"
test_pass "Prefer no match expected but accept just match path ends/with/nonnumber.txt:10a words"
test_pass "Accept just match path and lines no cols endswithlinebutnotcols.txt:10:20a"
test_pass "Accept just match path and lines no cols ends/with/linesbutnotcols.txt:10:20a"
test_pass "just_basename_filename_no_lines.py should match because extension"
test_pass "./dot_slash_filename_no_lines.py should match because extension"
test_pass "../dot_slash_filename_no_lines.py should match because extension"
test_pass "~/tilde_slash_filename.py should match because extension"
test_pass "~/path/tilde_path_filename.py should match"
test_pass "words just_basename_index.html should match"
test_pass "Match expected match_filename_but_not_nonnumberlines.txt:10a"
test_pass "Regrettable pass with word delim https://site/https_url_match_from_site_index.html"
test_fail "No match expected basename :23 15:16 ~nope no~pe there"
test_fail "No match expected AC/DC Giri/Haji oneslash/isnotenough"
test_fail "No match expected slash/path with spaces/isnotenough"
test_fail "Math tests: 3.14 and 5/3.14 should not match"
test_fail "Things like structure.member and product.price should not match. Often file extensions will be less than 5 chars."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment