Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to trim string variables in bash

Tags:

linux

bash

I have strings that initially contain different directory paths, where both the 2nd and 2nd last sub-directories can vary in length, like so

 /home/Leo/Work/CMI/ARCH/MWS/Disks
 /home/Cleo/Work/CMI/ARCH/BK/Disks

I want to trim the first 5 sub-directories and only show the last 2, like so

 echo "/MWS/Disks"
 echo "/BK/Disks"

One way to trim the first 5 sub-directories from the initial strings might be to left-shift each character until both strings start with the second last '/'.

The Bash Beginners Guide describes a shift built-in that left-shifts positional parameters in a command and throws away unused arguments. But it is not immediately obvious whether this could be used to trim the first 5 sub-directories from the strings described above.

In Bash, how do I reduce these strings, preferably without using loops ?


CLARIFICATION

Judging from comments a bit more context is needed. My Bash script recovers historic Mdos and Qdos files from 8-inch floppy disk images and saves files to directories on the hard drive.

For better or worse, I created a bespoke scheme that stores directory paths using 3-character variable names where each name is an acronym for the section of the path to the current directory.

For example MWC is an acronymn for $MY/Work/CMI in the following path

MY="$USER"
MWC="C:/cygwin64/home/$MY/Work/CMI"
cd "$MWC"
pwd
C:/cygwin64/home/$MY/Work/CMI

Similarly 3-character variables point to the next sub-directory further up the tree

WCA="$MWC/ARCH"

i.e. C:/cygwin64/home/$MY/Work/CMI/ARCH, path to a gallery of archive owners.

As directory paths lengthen the 3-character variables make paths easily identified by conserving white space in the listing. Nevertheless the full path appears whenever my script references a path. Hence the need to trim parts of the string that have no interest for the end user.

like image 806
Greg Avatar asked Oct 19 '25 14:10

Greg


1 Answers

If the number of subdirectories is always the same, you can use parameter expansion to remove the first 5 subdirectories:

s=/home/Leo/Work/CMI/ARCH/MWS/Disks
s=/${s#/*/*/*/*/*/}
echo $s  # /MWS/Disks

Or, if you know you need the last two parts whatever the depth of the path is:

s=/home/Leo/Work/CMI/ARCH/MWS/Disks
last=/${s##*/}
last_but1=${s%$last}
last_but1=/${last_but1##*/}
echo $last_but1$last  # /MWS/Disks
  • ${s#PATTERN} removes PATTERN from the beginning of $s.
  • ${s%PATTERN} removes PATTERN form the end of $s.
  • with # or %, the shortest match of PATTERN is found. Doubling them makes the match the longest possible.
like image 188
choroba Avatar answered Oct 21 '25 04:10

choroba



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!