for pathname in input/*.mcool; do
basename "${pathname%%.*}"
done
This iterates over all names in the directory input
that end in .mcool
. For each pathname in $pathname
, the pathname is truncated at the first dot using the standard parameter substitution ${pathname%%.*}
(removes the longest suffix string matching the pattern .*
from the value of $pathname
), and then basename
is used for extracting the filename portion of the pathname.
Testing:
$ tree
.
`-- input
|-- A001C001.something.mcool
|-- A001C002.something.mcool
|-- A001C003.something.mcool
|-- A001C004.something.mcool
|-- A001C005.something.mcool
|-- A001C006.something.mcool
|-- A001C007.something.mcool
|-- A001C008.something.mcool
`-- A001C009.something.mcool
2 directories, 9 files
$ for pathname in input/*.mcool; do basename "${pathname%%.*}"; done
A001C001
A001C002
A001C003
A001C004
A001C005
A001C006
A001C007
A001C008
A001C009
This assumes that the first dot in $pathname
occurs in the filename and not in the directory part of the pathname, which is why I don't start the pattern with ./
.
But we can turn it around to allow for dots in the directory path too, by calling basename
first:
for pathname in ./input/*.mcool; do
name=$(basename "$pathname")
printf '%s\n' "${name%%.*}"
done
If we know that that the suffix string we want to remove is exactly the string .something.mcool
(or .hg38.nodups.pairs.mcool
in your case), then the best solution would probably be something like
for pathname in ./input/*.something.mcool; do
basename "$pathname" .something.mcool
done
... which uses basename
to remove the known suffix from the pathname and return the filename portion of the pathname in one go, one pathname at a time.
With implementations of basename
that support the non-standard -a
and -s
options (for handling multiple files and removing a fixed suffix string from each), you could even get away without using a loop at all, if there are not too many files to process:
$ basename -a -s .something.mcool ./input/*.something.mcool
A001C001
A001C002
A001C003
A001C004
A001C005
A001C006
A001C007
A001C008
A001C009
See the basename(1)
manual on your system.
/
to the first.
after it". Or "from the last/
", if you just want the filename part of the full path regardless of how long the path is. The way you put it now, something like./a.b/c/x.y.z
would givex.y
and we'd need to count the dots that get removed from the left to know where to cut on the right.