1

I have a file of file paths. The depth of the directories is of various lengths and path names. I'd like to match two directories backwards (two /'s) and delete the match, creating a new file with the results.

eg:

/dir1/dir2/dir3/dir4/dir5/dir6/dir7/output_job3344.xml
/dir1/dir2/dir3/dir4/dir5/otherfile.txt

the result would be:

/dir1/dir2/dir3/dir4/dir5/dir6/
/dir1/dir2/dir3/dir4/

I tried something like this:

awk -F'/*./.*$' '{print $0}' deep.list

but that didn't work out.

peterh
  • 4,953
  • 13
  • 30
  • 44
Greg-905
  • 13
  • 2
  • Its not really a duplicate but sure. This question generated better answers too so in my opinion this is providing additional useful info. I searched for the solution before posting for at least 10 minutes without luck. "Similar" should be an option along with "duplicate". – Greg-905 Sep 06 '18 at 16:11
  • I wouldn't say duplicate since the answer is not the same. I agree it's similar, and one could study the answer to one and learn how to solve the other. – simlev Sep 07 '18 at 08:14

1 Answers1

0

Your idea is smart, but needs a few corrections. Here's how you probably meant it:

awk -F'[^/]*/[^/]*$' '{print $1}' deep.list

Explanation:

First thing, you probably misspelled .* as *..

Then, the * modifier is greedy, therefore you need to take care it doesn't match more than you intended! The solution is simple, albeit slightly less readable: use [^/]* instead of .*. This way you match any characters except /.

Lastly, $0 represents the entire line, which hasn't been altered in the slightest by specifying a specially crafted custom field separator. In this case you want to print the first field instead: $1.


Here's a different approach than the two answers linked by @ender.qa:

awk '{gsub("[^/]+/[^/]+$","");print}' deep.list

And one employing a loop:

awk -F/ '{for(i=1;i<=NF-2;i++){printf "%s/",$i}; print ""}' deep.list

The substitution method is more easily implemented in Perl:

perl -lape 's"[^/]+/[^/]+$""' deep.list

or sed:

sed -E 's"[^/]+/[^/]+$""' deep.list
simlev
  • 1,105
  • 3
  • 14
  • 22