2

I'm trying to do this on the mac terminal

I want to strip all the fields after the first dot on a filename but keep the extension at the end, and there can be an arbitrary length of dots.

Input:

file1.some.stuff.mp3 file2.other.stuff.stuff.mp3 file3.some.thing.mp3 file4.one.two.three.four.mp3

Expected output:

file1.mp3 file2.mp3 file3.mp3 file4.mp3

I have all the files on the same folder.

dibery
  • 2,760
  • 4
  • 16
  • 25
  • What have you tried so far and what did it emit? Edit your post to include this information. – Jeff Holt Jan 16 '20 at 16:13
  • Say that `f` is a variable with `file1.some.stuff.mp3` as value, `${f/.*/}` will result in `file1`. – accdias Jan 16 '20 at 16:17
  • 1
    Does this answer your question? [Split a string by awk and print everything but the last two splits](https://stackoverflow.com/questions/59773339/split-a-string-by-awk-and-print-everything-but-the-last-two-splits) – Corentin Limier Jan 16 '20 at 16:17

3 Answers3

4

As long as the filenames are guaranteed to have at least one . with non-empty strings preceding and following a ., this is a matter of simple parameter expansions.

for f in file1.some.stuff.mp3 file2.other.stuff.stuff.mp3 file3.some.thing.mp3 file4.one.two.three.four.mp3; do
    echo "${f%%.*}.${f##*.}"
done

produces

file1.mp3
file2.mp3
file3.mp3
file4.mp3

In the directory where the files exit, use something like

for f in *.mp3; do

to iterate over all MP3 files.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • Yes! this prints in console what i need but with the echo it only prints it in console it doesnt change the actual file names, which command could i use to do that action? – moises chin Jan 16 '20 at 16:58
  • `mv -- "$f" "${f%%.*}.${f##*.}"`, but I would recommend making sure that this doesn't result in two or more original files being renamed the same before actually executing the `mv` command. – chepner Jan 16 '20 at 17:01
  • Yep thanks i actually almost butchered a lot of files there that worked like a charm! – moises chin Jan 16 '20 at 21:04
2

Using bash variable substitution you may achieve the following:

for i in file1.some.stuff.mp3 file2.other.stuff.stuff.mp3 file3.some.thing.mp3
do
  echo "${i/.*./.}"
done

${i/.*./.} means to replace .*. by .. That is, it will match .some.stuff. in file1.some.stuff.mp3 and .b.c.d. in a.b.c.d.e.

In the parameter expansion section of man bash:

${parameter/pattern/string} Pattern substitution. The pattern is expanded to produce a pattern just as in pathname expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string.

dibery
  • 2,760
  • 4
  • 16
  • 25
0
for i in `ls *.mp3`; do NAMES=`echo $i|cut -d. -f1`; mv "$i" "$NAMES.mp3"; done
Riz
  • 1,131
  • 1
  • 9
  • 12