3

I am presently writing a Bash function to convert all the man pages listed by equery files <PACKAGE> | grep /usr/share/man/man (if you are unfamiliar equery is a tool used on Gentoo-based systems that is from the app-portage/gentoolkit package) into HTML files and one bit of information I need in order to do this is how I can remove everything but the man page's name, without its file extension, from its full path. I realize this phrasing may be confusing so I will explain what I mean by this with an example. Running equery files sys-apps/portage | grep /usr/share/man/man gives the output:

/usr/share/man/man1
/usr/share/man/man1/dispatch-conf.1.bz2
/usr/share/man/man1/ebuild.1.bz2
/usr/share/man/man1/egencache.1.bz2
/usr/share/man/man1/emaint.1.bz2
/usr/share/man/man1/emerge.1.bz2
/usr/share/man/man1/emirrordist.1.bz2
/usr/share/man/man1/env-update.1.bz2
/usr/share/man/man1/etc-update.1.bz2
/usr/share/man/man1/fixpackages.1.bz2
/usr/share/man/man1/quickpkg.1.bz2
/usr/share/man/man1/repoman.1.bz2
/usr/share/man/man5
/usr/share/man/man5/color.map.5.bz2
/usr/share/man/man5/ebuild.5.bz2
/usr/share/man/man5/make.conf.5.bz2
/usr/share/man/man5/portage.5.bz2
/usr/share/man/man5/xpak.5.bz2

out of this output say I take the final line /usr/share/man/man5/xpak.5.bz2 (which in the wording I used previously is this man page's full path), for the purpose of my example. Then what I would want to extract from it, within a Bash script, is xpak.5 (which is its file name, without its extension). How would I do this? I am presently using this Bash function:

function manhtmlp {
  for i in `equery files "$1" | grep /usr/share/man/man`
  do
    bzcat $i | mandoc -Thtml > $HOME/GitHub/fusion809.github.io/man/${i}.html
    sudo chmod 777 -R $HOME/GitHub/fusion809.github.io/man/${i}.html
  done
}

on the fifth and sixth lines I use the notation ${i} to indicate where I would like to be able to prune the man page's full path for its file name (without its extension). The user-supplied input (denoted by $1 in this function) denotes the name of a package, including its category (e.g., it would equal sys-apps/portage for the Portage package manager).

EDIT: Why this question is distinct from Stripping directory paths to get file names.

This previous question's answers while similar to what I would like do not tell one how to strip file extensions away from file names, only the rest of their path. So in the example of /usr/share/man/man5/xpak.5.bz2 the answer to the aforementioned question would provide one a way to get xpak.5.bz2 out of this full file path, but not xpak.5.

Josh Pinto
  • 3,483
  • 15
  • 52
  • 87
  • This may helpful: `basename /usr/share/man/man5/xpak.5.bz2 | sed 's/\(.*\)\..*/\1/'` will return file-name without extension! – Pandya Dec 18 '15 at 06:19

2 Answers2

7

Using parameter expansion:

line="/usr/share/man/man5/xpak.5.bz2"
 # printf "%s\n" "${line##*/}"                                     
 # xpak.5.bz2
file="${line##*/}"
printf "%s\n" "${file%.*}"
xpak.5

In Zsh, you can do nested parameter expansions:

printf "%s\n" "${${line##*/}%.*}"
xpak.5
jasonwryan
  • 71,734
  • 34
  • 193
  • 226
  • Definitely sounds like you're on the right track, but is there a way to do this in a single line, say with the dummy variable `$i`? Like would `${i##*/%.*}` do the trick? – Josh Pinto Dec 18 '15 at 06:20
  • @BrentonHorne I think you can play with your `grep` expression, for example this strips out the directory paths: `grep -Po '/usr/share/man/man.*/\K[^/]+\.bz2$'` (hat-tip to this [SO answer](http://stackoverflow.com/a/24679492/1144592) on how to use `\K` with the `-Po` flags) – h.j.k. Dec 18 '15 at 07:48
3

Using basename:

NAME
       basename - strip directory and suffix from filenames

SYNOPSIS
       basename NAME [SUFFIX]
       basename OPTION... NAME...

DESCRIPTION
       Print NAME with any leading directory components removed.  If specified, also remove a trailing SUFFIX.

Example:

$ file="/usr/share/man/man5/xpak.5.bz2"
$ echo "$(basename "$file" .bz2)"
xpak.5

You can also use sed if suffix is unknown:

$ file="/usr/share/man/man5/xpak.5.bz2"
$ echo "$(basename "$file" | sed 's/\(.*\)\..*/\1/')"
$ xpark.5
Pandya
  • 23,898
  • 29
  • 92
  • 144