I have a requirements in UNIX command
where i have a path similar to this:
path/to/file/manyfiles.extensions
now i want the output something similar to-
file/manyfiles.extensions
now i can do this listing both /path/to and /path removing them one by one.
but i might get only "/path/to" as my input and i have to remove both from the tree in one command.
You might think that i can list 2 folders to remove, but in many a cases i get structures having 12-13 of subfolders in which i need only the first and last folder in many cases.
eg - `Source files - target/classes/
Remove prefix - target`
Result:
classes/my/code/HelloWorld.class
classes/my/code/HelloWorldImpl.class
classes/my/code/Main.class
If I understand your question correctly, you want to strip off some given prefix on a path. Given a declaration path=/a/path/to/a/directory
and a pattern *a/
you can strip off the prefix matching that pattern in two ways in Bash:
echo ${path#*a/} # outputs "path/to/a/directory"
echo ${path##*a/} # outputs "directory"
The first variant is non-greedy and stops at the first match, while the second is greedy and stops at the longest possible match for the pattern. The pattern *a/
occurs twice in out path here, so the results are then different.
In your case the pattern would be something like path/to
and the path path/to/file/manyfiles.extensions
, so one of the following would work, depending on whether you need to be greedy or not:
path=path/to/file/manyfiles.extensions
path=${path#*path/to/} # assigns "file/manyfiles.extensions" to $path
or
path=path/to/file/manyfiles.extensions
path=${path##*path/to/} # assigns "file/manyfiles.extensions" to $path
For reference, read about Bash parameter expansion.
You'll want to the basename
command to strip the directories off your filename, combined with the dirname
command which will give you just the directory structure.
You can then use whatever logic you require to get the parts of the directory you need to keep, and put it back together with the filename.
Something like in this pseudocode:
original_file='/some/long/path/to/a/file'
file_name=$(basename $original_file)
dir_name=$(dirname $original_file)
short_dir='...use regex or whatever logic you need to pear ${dir_name} down (we'll need more info to help with this)'
new_file="${short_dir}/${file_name}"
You can try grep -oP
:
p="older2/folder3/folder4/folder5/folder6/folder7/file.txt"
s=$(grep -oP '([^/]+/){2}[^/]+/?$' <<< "$p")
echo "$s"
OUTPUT:
folder6/folder7/file.txt