The way to Bulk Rename Information to Numeric File Names in Linux

The way to Bulk Rename Information to Numeric File Names in Linux


Need to rename an entire set of recordsdata to a numeric sequence (1.pdf, 2.pdf, 3.pdf, …) in Linux? This may be accomplished with some gentle scripting and this text will present you the best way to do precisely that.

Numeric File Names

Normally once we scan a PDF file utilizing some {hardware} (cell phone, devoted PDF scanner), the file title will learn one thing like 2020_11_28_13_43_00.pdf. Many different semi-automated programs produces comparable date and time primarily based filenames.

Generally the file may comprise the title of the appliance getting used, or another data like for instance the relevant DPI (dots per inch) or the scanned paper measurement.

When accumulating PDF recordsdata collectively from completely different sources, file naming conventions could differ considerably and it could be good to standardize on a numeric (or half numeric) file title.

This additionally applies to different domains and units of recordsdata. For instance, your recipes or picture assortment, knowledge samples generated automated monitoring programs, log recordsdata prepared for archiving, a set of SQL recordsdata for the database engineer, and usually any knowledge collected from completely different sources with completely different naming schemes.

Bulk Rename Information to Numeric File Names

In Linux, it’s straightforward to shortly rename an entire set of recordsdata with utterly completely different file names, to a numerical sequence. “Simple” means “straightforward to execute” right here: the issue of bulk renaming recordsdata to numerical numbers is advanced to code in itself: the oneliner script under took 3-4 hours to analysis, create and check. Many different instructions tried all had limitations which I needed to keep away from.

Please word that no warranties are given or offered, and this code is offered ‘as is’. Please do your individual analysis earlier than working it. That mentioned, I did check it efficiently in opposition to recordsdata with numerous particular characters, and in addition in opposition to extra then 50k recordsdata with none file being misplaced. I additionally checked a file named 'a'$'n''a.pdf' which accommodates a newline.

if [ ! -r _e -a ! -r _c ]; then echo 'pdf' > _e; echo 1 > _c ;discover . -name "*.$(cat _e)" -print0 | xargs -0 -I{} bash -c 'mv -n "{}" $(cat _c).$(cat _e);echo $[ $(cat _c) + 1 ] > _c'; rm -f _e _c; fi

Let’s first have a look at how this works, after which analyze the command. We’ve got a created a listing with eight recordsdata, all named fairly in another way, besides their extension matches and is .pdf. We subsequent run the command above:

Bulk Rename Files to Numeric File Names in Linux

The result was that the 8 recordsdata have been renamed to 1.pdf, 2.pdf, 3.pdf, and so forth., regardless that their names had been fairly offset earlier than.

The command assumes you would not have any 1.pdf to x.pdf named recordsdata but. Should you do, you’ll be able to transfer these recordsdata right into a separate listing, set the echo 1 to a better quantity to begin the renaming the remaining recordsdata at a given offset, after which merge the 2 directories collectively once more.

Please all the time take care to not overwrite any recordsdata, and it’s all the time a good suggestion to take a fast backup earlier than updating something.

Let’s have a look at the command intimately. It will probably assist to see what is going on by including the -t choice to xargs which lets us see what’s going on behind the scenes:

xargs with -t option lets us see what is happening during the rename process

To start out, the command makes use of two small non permanent recordsdata (named _e and _c) as non permanent storage. At the beginning of the oneliner it does a security test utilizing an if assertion to make sure that each _e and _c recordsdata aren’t current. If there’s a file with that title, the script won’t proceed.

On the subject of utilizing small non permanent recordsdata versus variables, I can say that whereas utilizing variables would have been preferrred (saves some disk I/O), there have been two points I used to be working into.

The primary one is that should you EXPORT a variable at the beginning of the oneliner after which use that very same variable later, if one other script makes use of the identical variable (together with this script run extra then as soon as concurrently on the identical machine), then that script, or this one, could also be affected. Such interference is greatest averted in relation to renaming many recordsdata!

The second was that xargs together with bash -c appears to have a limitation in variable dealing with contained in the bash -c command line. Even intensive analysis on-line didn’t present a workable answer for this. Thus, I ended up utilizing a small file _c which maintain progress.

_e Is the extension we might be looking for and utilizing, and _c is a counter which might be mechanically elevated on every rename. The echo $[ $(cat _c) + 1 ] > _c code takes care of this, by displaying the file with cat, including one quantity, and re-writing it.

The command additionally makes use of the absolute best technique of dealing with particular file title characters by utilizing null-termination as an alternative of the usual newline termination, i.e. the character. That is ensured by the -print0 choice to discover, and by the -0 choice to xargs.

The discover command will seek for any recordsdata with the extension as specified within the _e file (created by the echo 'pdf' > _e command. You’ll be able to range this extension to another extension you need, however please don’t prefix it with a dot. The dot is already included within the later *.$(cat _e) -name specifier to discover.

As soon as discover has positioned all of the recordsdata and despatched them – terminated to xargs, xargs will rename the recordsdata one after the other utilizing the counter file (_c) and the identical extension file (_e). To acquire the contents of the 2 recordsdata, a easy cat command is used, executed from inside a subshell.

The mv transfer command makes use of -n to keep away from overwriting any file already current. Lastly we cleanup the 2 non permanent recordsdata by eradicating them.

Whereas the price of utilizing two state recordsdata and subshell forking could also be restricted, this does add some overhead to the script, particularly when coping with a considerable amount of recordsdata.

There are all kinds of different options for this similar drawback on-line, and lots of have tried and didn’t create a completely working answer. Lots of options forgot all kinds of facet instances, like utilizing ls with out specifying --color=by no means, which can result in hex codes being parsed when listing itemizing shade coding is used.

But different options missed dealing with recordsdata with areas, newlines and particular characters like ‘’ accurately. For this, the mix discover ... -print0 ... | xargs -0 ... is normally indicated and preferrred (and each the discover and xargs manuals allude to this reality fairly strongly).

Whereas I don’t think about my implementation the proper or finish answer, it appears to make a major furtherance to lots of the different options on the market, by utilizing discover and terminated strings, guaranteeing most filename and parsing compatibility, in addition to having a number of different niceties like with the ability to specify a beginning offset, and being totally Bash-native.

Get pleasure from!

Source link