use sed to get a list of different paths up to a point

Viewed 49

I have a list of filepaths that look like this

abc/def/ghi/jl/r1/r2
abc/def/ghi/jl/r9/r11
abc/nyc/ghi/jl/r3/r4/r5
abc/nyc/ghi/jl/pan21/nab11
def/kyn/ghi/jl/r6
...

all paths have the sub-paths /ghi/jl/

I would like to get a list of different paths ending at /ghi/jl/ so for the example above I would get

abc/def/ghi/jl/
abc/nyc/ghi/jl/
def/kyn/ghi/jl/

Can this achieved with sed (or something similar)? I tried

sed 's/\/ghi\/jl\/.*/\/ghi\/jl\//' listfile

but didnt quite get it.

5 Answers

perl -ne '/(^.*?\/ghi\/jl)/; print "$1\n";' listfile | sort -u

should do the trick.

Using awk

awk -F/ '{print $1 "/" $2 "/" $3 "/" $4 "/"}' /path/to/your/file

-F/ tells awk to use / as a delimiter for splitting input.

Using cut and sed

{ cut -d '/' -f -4 | sed 's/$/\//'; } < /path/to/your/file

Here, the cut command splits each line in the input file, and then outputs the first 4 fields (-f -4 tells cut to output the first 4 fields). Then the sed command appends / onto the end of each line output by cut.

If the trailing / on each output line is not required, this simplifies to

cut -d '/' -f -4 /path/to/your/file

Using sed and sort:

sed -ne 's|^\(.*/ghi/jl/\).*|\1|p' -- data | sort -u

or,

somedir='/ghi/jl/'
sed -ne 's|^\(.*'"${somedir}"'\).*|\1|p' -- data | sort -u

where the substitution captures from start of line up to and including dirname.

Or perhaps, selecting dirnames with at least 4 slashes,

sed -n -e 's|/|\t|4' -e 's|\t.*|/|p' -- data | sort -u

where the first substitution replaces the fourth slash with a tab, the second replaces tab and following characters with the stripped slash.

Use grep like so:

grep -o '.*ghi/jl/' in_file

Here, grep uses option -o : Print the matches only (1 match per line), not the entire lines.

This might work for you (GNU sed):

sed -E '\#(.*/ghi/jl/).*#{s//\1/;H;g;s/((\n.*).*)\2$/\1/;h};$!d;x;s/.//' file

Store matches in the hold space making sure to remove any duplicates. At end of the file, switch to the hold space and print the results (less the introduced newline at the start of buffer).

Related