2

I am trying to come up with a bash script to remove parts of a file name on CentOS. My file names are:

119903_Relinked_new_3075_FileNote_07_02_2009_JHughes_loaMeetingAndSupport_FN_205.doc
119904_relinked_new_2206_Support_Intensity_Scale_SYCH_SIS_264549.pdf
119905_relinked_new_3075_Consent_07_06_2009_DSweet_CRFA_CF_16532.docx
29908_relinked_new_2206_Assessor_Summary_Report_SERT_I_OTH_264551.pdf
009712_relinked_new_3075_Consent_07_06_2009_CWell_DPRT_check_CF_16535.pdf

I would like to remove 119903_Relinked_new_ from the file names. The end result should be:

3075_FileNote_07_02_2009_JHughes_loaMeetingAndSupport_FN_205.doc
2206_Support_Intensity_Scale_SYCH_SIS_264549.pdf
3075_Consent_07_06_2009_DSweet_CRFA_CF_16532.docx
2206_Assessor_Summary_Report_SERT_I_OTH_264551.pdf
3075_Consent_07_06_2009_CWell_DPRT_check_CF_16535.pdf

I have been trying multiple scripts but coming up short. The number before _Relinked_new_ is different in most cases and the file extensions vary across .pdf, .docx, .doc etc. Any help would be appreciated.

2
  • And the R of relinked can be either r or R, is that right? Commented Apr 18, 2022 at 15:42
  • that is correct Commented Apr 18, 2022 at 15:43

3 Answers 3

5

Using the prename(1) tool (it might be called rename or prename or perl-rename depending on your system):

rename 's/[0-9]+_[rR]elinked_new_//' /path/to/dir/*

This will use a regular expression to match the pattern and replace it with nothing on the specified files.

4
  • worked like a charm, I used prename. Thank you for the help! Commented Apr 18, 2022 at 15:51
  • @mike87 If one of the answers here solved your issue, please take a moment and accept it by clicking on the checkmark on the left. That is the best way to express your thanks on the Stack Exchange sites. Commented Apr 18, 2022 at 15:52
  • The script works but I am trying to execute it on a directory with over 30k files and I get this message after about 45 seconds, ' -bash: /usr/bin/prename: Argument list too long ' Commented Apr 18, 2022 at 16:10
  • 1
    @mike87, that's not the fault of the tool, you'd get the same with ls * or so. See e.g. Solving "mv: Argument list too long"?. Commented Apr 18, 2022 at 19:06
5

Without the rename tool, using a simple shell loop with parameter substitution to rename a file at a time:

for name in /path/to/dir/*_[rR]elinked_new_*
do
    newname=${name##*/}
    newname=${name%/*}/${newname#*_[rR]elinked_new_}

    # or:
    # newname=$(basename "$name")
    # newname=$(dirname "$name")/${newname#*_[rR]elinked_new_}

    mv -- "$name" "$newname"
done

Inside the loop, the value of newname is first computed as the filename component of the name variable (the last bit after the last slash in the pathname).

The newname variable is then modified by pretending it with the directory path and the result of removing whatever text matches the shell pattern *_[rR]elinked_new_ from the start of the filename.

The code can be simplified somewhat by first changing the current directory into the directory where the files are located:

cd /path/to/dir || exit

for name in *_[rR]elinked_new_*
do
    newname=${name#*_[rR]elinked_new_}
    mv -- "$name" "$newname"
done
0
2

This is really just a comment in response to your problem with "Argument list too long", but it started to look messy in the comment box, so now it's an answer. :)

The reason you're getting that error is that * tries to put every file in the directory onto the command line, which has length restrictions. Instead you can loop over the files (or use find to do a similar thing) and call rename on each individually:

find /path/to/dir -iname '*relinked_new_*' -exec prename 's/[0-9]+_[rR]elinked_new_//' {} \;
1
  • Using the xargs variant (find /path/to/dir -iname '*relinked_new_*' -print0 | xargs -0 prename 's/[0-9]+_[rR]elinked_new_//') would be more efficient, I guess. Commented Apr 19, 2022 at 12:06

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.