1

Cisco IOS routers, doing a "dir", and I want to grab all file names with ".bin" in the name.

Example string: Directory of flash0:/

1  -rw-    95890300  May 24 2015 11:27:22 +00:00  c2900-universalk9-mz.SPA.153-3.M5.bin
2  -rw-    68569216   Feb 8 2019 20:15:26 +00:00  c3900e-universalk9-mz.SPA.151-4.M10.bin
3  -rw-       46880  Oct 25 2017 19:08:56 +00:00  pdcamadeusrtra-cfg
4  -rw-         600   Feb 1 2019 19:36:44 +00:00  vlan.dat

260153344 bytes total (95637504 bytes free)

I've figured out how to pull "bin", but I can't figure out how to pull the whole filename (starting with " c", ending in "bin"), because I want to then use the values and delete unwanted files.

I'm new to programming, so the regex examples are a little confusing.

Brian Koch
  • 11
  • 1
  • 5

3 Answers3

1

You can use this regex

^[\w\W]+?(?=(c.*\.bin))\1$
  • ^ - Start of string.
  • [\w\W]+? - Match anything one or more time ( Lazy mode ).
  • (?=(c.*\.bin)) - Positive lookahead match c followed by anything followed by \.bin ( Group 1)
  • \1 - Match group 1.
  • $ - End of string.

Demo

Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • that works, but then only returns the last instance found: ok: [10.35.91.200] => changed=false ansible_facts: binfiles: - c2800nm-adventerprisek9-mz.151-4.M12a.bin – Brian Koch Feb 11 '19 at 17:14
  • @what do you mean ? did you checked you used proper flags ? – Code Maniac Feb 11 '19 at 17:23
  • Here's the statement: binfiles="{{ dir_response.stdout[0] | regex_findall('[\w\W]+?(?=(c.*\.bin))\1$') }}" This is the result: TASK [set_fact] ******************************************************************************************************** task path: /export/home/e130885/playbooks/ios-switch-upgrade/ios_clean_flash.yml:16 Monday 11 February 2019 11:31:47 -0600 (0:00:00.386) 0:00:03.037 ******* ok: [10.35.91.200] => changed=false ansible_facts: binfiles: - c2800nm-adventerprisek9-mz.151-4.M12a.bin META: ran handlers META: ran handlers Thank you! – Brian Koch Feb 11 '19 at 17:32
  • And what does `"{{ dir_response.stdout[0] }}` by its onesie look like? – tink Feb 11 '19 at 18:26
  • TASK [debug] *********************************************************************************************************** Monday 11 February 2019 12:46:17 -0600 (0:00:02.752) 0:00:02.815 ******* ok: [10.35.91.200] => msg: - |- 1 -rw- 95890300 May 24 2015 11:27:22 +00:00 c2900-universalk9-mz.SPA.153-3.M5.bin 2 -rw- 68569216 Feb 8 2019 20:15:26 +00:00 c3900e-universalk9-mz.SPA.151-4.M10.bin 5 -rw- 67929600 Feb 8 2019 21:24:56 +00:00 c2800nm-adventerprisek9-mz.151-4.M12a.bin – Brian Koch Feb 11 '19 at 18:46
0

To match the filename that start with a c (or at the start of the string) you might use a negative lookbehind (?<!\S) to check what is on the left is not a non-whitespace character.

Then match either 1+ times not a whitespace character \S+ or list in a character class [\w.-]+ what the allowed characters are to match. After that match a dot \. followed by bin.

At the end you might use a word boundary \b to prevent bin being part of a larger word:

(?<!\S)[\w.-]+\.bin\b

regex101 demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
0

Thank you Code Maniac! Your code finds one instance, and I needed to find all. Using what you gave me plus messing around with some other examples, I found this to work:

binfiles="{{ dir_response.stdout[0] | regex_findall('\b(?=(c.*.bin))\b') }}"

Now I get this: TASK [set_fact] ******************************************************************************************************** task path: /export/home/e130885/playbooks/ios-switch-upgrade/ios_clean_flash.yml:16 Tuesday 12 February 2019 08:29:58 -0600 (0:00:00.350) 0:00:03.028 ****** ok: [10.35.91.200] => changed=false ansible_facts: binfiles: - c2900-universalk9-mz.SPA.153-3.M5.bin - c3900e-universalk9-mz.SPA.151-4.M10.bin - c2800nm-adventerprisek9-mz.151-4.M12a.bin

Onto the next task of figuring out how to use each element. Thank you!

Brian Koch
  • 11
  • 1
  • 5