Batch Rename Files Using Bash

How does Bash rename a series of packages to remove their version numbers? I circumvented using expr and %% , but to no avail.

Examples:

Xft2-2.1.13.pkg becomes Xft2.pkg

jasper-1.900.1.pkg becomes jasper.pkg

xorg-libXrandr-1.2.3.pkg becomes xorg-libXrandr.pkg

+71
bash shell file-rename
Mar 02 '09 at 15:20
source share
7 answers

You can use the bash extension function

 for i in *.pkg ; do mv "$i" "${i/-[0-9.]*.pkg/.pkg}" ; done 

Quotes are required for file names with spaces.

+135
Mar 02 '09 at 15:33
source share
— -

If all files are in the same directory, the sequence

 ls | sed -n 's/\(.*\)\(-[0-9.]*\.pkg\)/mv "\1\2" "\1.pkg"/p' | sh 

will do your job. The sed command will create a sequence of mv commands that you can then pass to the shell. Best to start a pipeline without training | sh to make sure that the command does what you want.

For reprocessing across multiple directories, use something like

 find . -type f | sed -n 's/\(.*\)\(-[0-9.]*\.pkg\)/mv "\1\2" "\1.pkg"/p' | sh 
+22
Mar 02 '09 at 15:54
source share

I will do something like this:

 for file in *.pkg ; do mv $file $(echo $file | rev | cut -f2- -d- | rev).pkg done 

it is assumed that your entire file is in the current directory. If not, try using find as described above by Javier.

EDIT . In addition, this version does not use any bash-specific functions, as above, which leads to greater portability.

+6
Mar 02 '09 at 15:35
source share

it is better to use sed for this, something like:

 find . -type f -name "*.pkg" | sed -e 's/((.*)-[0-9.]*\.pkg)/\1 \2.pkg/g' | while read nameA nameB; do mv $nameA $nameB; done 

calculating a regular expression remains as an exercise (as it does with file names that include spaces)

+3
Mar 02 '09 at 15:30
source share

This seems to work, assuming that

  • it all ends in $ pkg
  • Your version # always starts with "-"

cancel .pkg, then separate - ..

 for x in $(ls); do echo $x $(echo $x | sed 's/\.pkg//g' | sed 's/-.*//g').pkg; done 
+2
Mar 02 '09 at 15:33
source share

I had several *.txt files that were renamed to .sql in the same folder. below worked for me:

 for i in \`ls *.txt | awk -F "." '{print $1}'\` ;do mv $i.txt $i.sql; done 
+2
Nov 05 '15 at 17:22
source share

Thanks for answers. I also had some kind of problem. Moving .nzb.queued files to .nzb files. There were spaces and other cracks in the file names, and this solved my problem:

 find . -type f -name "*.nzb.queued" | sed -ne "s/^\(\(.*\).nzb.queued\)$/mv -v \"\1\" \"\2.nzb\"/p" | sh 

It is based on the answer of Diomidis Spinellis.

The regular expression creates one group for the entire file name and one group for the part before .nzb.queued, and then creates a shell move command. With quoted strings. It also avoids creating a loop in the shell script, as sed has already done so.

0
Oct 30 '14 at 8:53
source share



All Articles