I have a path like this C:\Users\Administrator\Desktop\Photos-or\3-PRO\3-1-CR\CR-RESTS\LES-COQS\1920x500 and I'd like a regex to match the grandparent folder which, in this case, is LES-COQS.

I've tried:

echo "C:\Users\Administrator\Desktop\Photos-or\3-PRO\3-1-CR\CR-RESTS\LES-COQS\1920x500" | grep -i "[a-zA-Z0-9-]*\\\[0-9a-z]*$"

Should I use a lookahead/lookbehind ? Or is there a simpler way ?


  • 4
    That doesn't look like a path. Path components are / separated on Unix. Assuming you mean a MS-DOS path, I don't see LESCOQS in it, only LES-COQS which would be the directory containing the 1920x500 file, not its grandparent by any meaning of grandparent. Also, it's not clear what you mean by matching here. What's the output you're expecting? Dec 11, 2020 at 8:05
  • @StéphaneChazelas I would assume that 1920x500 is itself a directory and thus a "parent" of some unspecified file. Louis, is that right?
    – TooTea
    Dec 11, 2020 at 8:41
  • it's a windows path, and I need a pure regex solution.
    – Louis
    Dec 11, 2020 at 13:49
  • @TooTea yes right, the 1920x500 is the parent of some file indeed.
    – Louis
    Dec 11, 2020 at 16:55
  • wrt I need a pure regex solution - so this is homework, right? Otherwise you wouldn't use a regexp for this.
    – Ed Morton
    Dec 12, 2020 at 23:54

4 Answers 4


Assuming you want to output the second-last component of that MS-DOS-style path, you could do:

expr "\\$msdos_path" : '.*\\\(.*\)\\.*'

Which here would output LES-COQS.

  • $ echo "C:\Users\Administrator\Desktop\Photos-originals\3-PROFESSSIONELS\3-1-CHR\CHR-RESTAURANTS\LESFRANGINS\1920x500" | grep -i '(.*)\\.*' returns the whole string. This doesn't work.
    – Louis
    Dec 11, 2020 at 16:57
  • 1
    @Louis, grep is the tool to print the lines that match a regexp (that's named after the g/re/p command in ed) while here you want to extract a part of a string (which as it it's a path could be made of several lines), and so expr is a better tool for the task. Dec 11, 2020 at 17:03

There are many ways to extract the penultimate item from the path. Here are a few with a mix of solution approaches


echo "$p" | grep -oP '.*\\\K[^\\]*(?=\\[^\\]+)'     # PCRE
echo "$p" | sed 's!^.*\\\([^\\]*\)\\[^\\]*$!\1!'    # RE

echo "$p" | awk -F'\\' '{print $(NF-1)}'            # Awk

IFS='\\' ps=($p); echo "${ps[-2]}"                  # Shell (bash)
px="${p%\\*}"; echo "${px##*\\}"                    # Shell

The expressions are much harder to read due to each backslash in the Windows folder path having to be matched by a double backslash in each RE pattern. (In fact, I worked on a couple of these by replacing \ with / throughout.)


May be this will help you to get the expected result

# GNU bash, version 4.4.20
echo "C:\Users\Administrator\Desktop\Photos-or\3-PRO\3-1-CR\CR-RESTS\LES-COQS\1920x500" | rev | awk -F'\' '{ print $2 }' | rev

Output :


Tested on : https://rextester.com/l/bash_online_compiler


You can use sed with extended regular expression and the substitution command:

$ echo "C:\Users\Administrator\Desktop\Photos-or\3-PRO\3-1-CR\CR-RESTS\LES-COQS\1920x500" | sed -E 's/(.*\\)([^\\]+)(\\[^\\]+)/\2/'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.