-2

In my directory I have thousands of PDF files. I want to write a shell script where goes through all the files and trims the last 16 characters and and saves back to the directory without keeping the old filename.

Now: KUD_1234_Abc_DEF_9055_01.pdf

New: KUD_1234.pdf

How can I solve that.

Thank you all

Cyrus
  • 84,225
  • 14
  • 89
  • 153
KaanEm
  • 31
  • 1
  • 2
  • 2
    Don't forget to describe the handling of name collision with files having the same name after trimming the last 16 characters. – Léa Gris Oct 13 '21 at 14:19
  • 2
    simple [Parameter Expansion](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html) will do what you want if your filename format is as consistent as you imply. Please try that and show us an attempt. Don't overcomplicate it. Someone will help you refine it - I'd be happy to. Just do your part. – Paul Hodges Oct 13 '21 at 14:20

2 Answers2

2

To the importance of analyzing and describing a problem properly to find a proper solution.

Here I implement exactly what you ask for:

#!/usr/bin/env sh

for oldname
do
  # Capture old file name extension for re-use, by trimming-out the leading
  # characters up-to including the dot
  extension=${oldname##*.}

  # Capture the old name without extension
  extensionless=${oldname%.*}

  # Compose new name by printing the old file name
  # up to its length minus 16 characters
  # and re-adding the extension
  newname=$(
    printf '%.*s.%s\n' $((${#extensionless}-16)) "$extensionless" "$extension"
  )

  # Demonstrate rename as a dummy 
  echo mv -- "$oldname" "$newname"
done

Works for your sample case:

mv -- KUD_1234_Abc_DEF_9055_01.pdf KUD_1234.pdf

Will collide not rename this:

mv -- KUD_1234_ooh_fail_666_02.pdf KUD_1234.pdf

Will not work with names shorter than 16 characters:

mv -- notwork.pdf notwork.pdf

Will probably not do what you expect if name has no dot extension:

mv -- foobar foobar.foobar
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
-1

This should work for you (please backup data before trying):

find -type f | sed -E 's|^(.+)(.{16})(\.pdf)$|\1\2\3\ \1\3|g' | xargs -I f -- bash -c "mv f"

However, it's much easier to do it with python:

import os
os.chdir("/home/tkhalymon/dev/tmp/empty")
for f in os.listdir("."):
    name, ext = os.path.splitext(f)
    os.rename(f, f"{name[:-16]}{ext}")
Taras Khalymon
  • 614
  • 4
  • 11