0

I have the files as below. There are four files in total:

cert1.pem chain1.pem fullchain1.pem privkey1.pem

I want to trim the tail number of each file (1 here). How do I use a shell script to handle it automatically? I am familiar with some commands, but I think I am not good at writing shell scripts to handle this batch processing.

1 Answer 1

4

If the trailing number is a single digit, and they are all .pem files, you could use parameter expansion to strip the digit and extension, then replace the extension:

for file in cert1.pem  chain1.pem  fullchain1.pem  privkey1.pem
do
  mv "$file" "${file%%?.pem}.pem"
done

The parameter expansion works by removing the longest trailing match (%%) of any single character (?) followed by .pem; after that is done, we manually add back the .pem at the end.

Note that this would also rename files like certX.pem or fullchain-.pem, because the ? character expands to any single character.

This is made safer in the above example because I've manually listed the files to rename. You could alternatively use something like:

for file in *1.pem
do
  mv "$file" "${file%%?.pem}.pem"
done

... which loops explicitly over files with 1.pem at the end of their names.

Setup:

$ ls
cert1.pem  chain1.pem  fullchain1.pem  privkey1.pem

Execution:

$ for file in cert1.pem  chain1.pem  fullchain1.pem  privkey1.pem
  do 
    mv "$file" "${file%%?.pem}.pem"
  done

Result:

$ ls
cert.pem  chain.pem  fullchain.pem  privkey.pem
4
  • It works. A comprehensible solution~
    – jefferyear
    Commented Jul 6, 2018 at 5:16
  • I have a question. I used "${file%%?.*}.pem", "${file%?.*}.pem" and "${file%?.pem}.pem". All of them are also workable. Why? If I used ${file%%.*} or ${file%%.pem}, they are not workable. I think I am able to use asterisk to replace "pem" this word. I also know "%" it will start from the tail. It is different to "#" this symbol. I know "?" its meaning. But, why "?" is important in here for purpose to trim the tail?
    – jefferyear
    Commented Jul 6, 2018 at 9:09
  • Using .* means it would match (remove) any "extension" (characters after a period) instead of just "pem". Using a single % is a good choice here, since you want to remove the shortest match, not the longest (%%). Your filenames didn't look like file1.pem1.pem so there's not a practical difference.
    – Jeff Schaller
    Commented Jul 6, 2018 at 10:54
  • If I regard "?" as its purpose to parse its front word as none or something, am I right in here? I used ${file%.*}, ${file%%.*}, ${file%.pem} and ${file%%.pem}. The output shows up "are the same file".
    – jefferyear
    Commented Jul 9, 2018 at 3:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .