11

I receive from the user a certain absolute filepath, and I want to create a variable that will be a string that won't include only the FIRST two components of the file path, but without printing it or anything.

For example, the absolute path could be:

/home/myusername/folder1/folder2/folder3

And it's saved in "target_path", and I want "mydir" to be only:

/folder1/folder2/folder3

I tried using the cut command in different ways but without success.

  • Is /home/username the actual $HOME directory of the invoking user? if so you could remove it simply using mydir="${target_path#$HOME}" I think – steeldriver Nov 10 '16 at 14:02
15

Using bash's string manipulation:

$ a=/home/myusername/folder1/folder2/folder3
$ echo "${a#/*/*/}"
folder1/folder2/folder3

So, the string you want would be (adding back the leading slash):

b="/${a#/*/*/}"

For a variable a, ${a#foo} will remove the shortest string matching foo from the start of a. So, we remove the shortest string containing three / (including the leading slash in the path), to remove the first two components of the absolute path.

  • The path might be 30 folders, and I only want to include the last 28. Will this still work? – Life of pi Nov 10 '16 at 14:15
  • @Lifeofpi why not? – muru Nov 10 '16 at 14:16
9

Here is an example using cut

echo "/home/myusername/folder1/folder2/folder3" | cut -d '/' -f4- 

folder1/folder2/folder3

If you need the leading / you could append | sed 's/^/\//' to the end of your line.

You need -f4- because -d '/' tells cut to use / as a delimiter between fields. So the first field comes before the first delimiter, in this case the first field is empty. So folder1 is the 4th field and -f4- tells cut to use all fields from the 4th onwards.

7

You can use bash parameter expansion like so:

target_path=/home/username/folder1/folder2/folder3
myvar="/${target_path#/*/*/}"

After this:

echo $myvar

gives:

/folder1/folder2/folder3

It works by removing the first match of the pattern /*/*/ from your target_path variable, by using the ${target_path#pattern} shell parameter expansion syntax. Unfortunately this removes the first / character, which is why that character must be explicitly included while setting the myvar variable.

Warning: You should check that your target_path variable contains some characters, and is longer than two path segments before using this method. For instance if target_path=/home/username/, then myvar=/. This could be dangerous to your system if you're running something like rm -rf "$myvar"*. Don't try this!

  • The path might be 30 folders, and I only want to include the last 28. Will this still work? – Life of pi Nov 10 '16 at 14:16
  • Definitely, this will only trim the first two, no matter what length the path is. – Arronical Nov 10 '16 at 14:18

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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