Bash script to change a filename associated with an inode index number.
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Bash script to change a filename associated with an inode index number.
I am trying to write a BASH script that will search through a directory and find filenames with illegal characters in them then find the inode associated with the file and then change the filename associated to that inode number to a legal name by stripping out illegal chars and replacing them with underscores.
I have a piece of code that is in the right direction. It finds illegal names and removes them.
With code like this:
//Remove by filenames with illegal chars.
find . -name '*[+{;"\\=?~()<>&*|$ ]*' -exec rm -f '{}' \;
or
//Remove by passing an inode number.
find . -inum $inum -exec rm {} \;
Instead of removing the file I want to keep the file but change the filename associated with the inode number.
Missing pieces that I think i still need:
Method of stripping the bad filename of illegal chars and replacing them with underscores. I assume there will need to be a string variable that holds the old name and then is processed and then stored in a new name variable.
These two variables could be used with a move (mv) command to change the bad name.
Is there a direct way to update the name associated with an inode number, without using mv?
I am still working on finding the solution to this and I will post what I find, but any help out there would be great.
When I try it at the command line, it gives me trouble with the filenames, depending on the illegal chars it encounters in the name.
I was gonna warn about that:..
filename="A$(echo -en \\x01\\x10\\x0101\\x002\\x83)Z"
now try:
echo $filename | sed 's/[+{;"\\=?~()<>&*|$ ]/_/g'
vs:
echo ${filename//[^a-zA-Z0-9]/}
replacement:
Code:
retScrubbedString() { # Slow but no sed needed:
declare -r static_char_restr="1234567890-_./abcdefghijklmnopqrstuv\
wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
declare -r char_rpl="_"; str_arg=( $1 )
for charPos in $(seq 0 $(expr ${#str_arg[0]} - 1)); do
expr index "${str_arg[0]:${charPos}:1}" ${static_char_restr} >/dev/null
case "$?" in 1) str_arg_cpy_ok="${str_arg_cpy_ok}${char_rpl}";;
0) str_arg_cpy_ok="${str_arg_cpy_ok}${str_arg[0]:${charPos}:1}";;
esac; done; printf "%s${str_arg_cpy_ok}\n"; unset str_arg_cpy_ok; }
Tried your script, actually it outputs on my computer:
A___012_Z
Gonna take me a while to figure out exactly how that script works.
How about this, which I think has the same effect as your script, why not use sed with a more accurate regular expression?:
echo $filename | sed 's/[^0-9a-zA-Z_./-]/_/g'
I want the script to search the directory for bad filenames then replace the bad characters with underscores and mv the old badname to the new corrected filename.
I get the following output after running the script.
**********
#sh rename_filename_test.sh
mv: when moving multiple files, last argument must be a directory
Try `mv --help' for more information.
mv: `rename_filename_test.sh' and `rename_filename_test.sh' are the same file
**********
Should the script file be included in the mv?
None of the illegal characters are in the filename.
Also, should the file be in the same folder the script is running on?
Hmm, it works ok for me. Try copy the entire script and paste it into a text file called test. I have that file located in the directory and run it with the command: sh test
Originally posted by homey Hmm, it works ok for me. Try copy the entire script and paste it into a text file called test. I have that file located in the directory and run it with the command: sh test
I get the same type pf thing again...
# sh test
mv: `rename_filename_test.sh' and `rename_filename_test.sh' are the same file
mv: `test' and `test' are the same file
mv: `rename_filename_test.sh' and `rename_filename_test.sh' are the same file
mv: `test' and `test' are the same file
That's because those files are already changed to the underscore type of name so the move command gets a little confused about it. No harm done and the script is working.
1) It doesn't seem to be changing the "[" or "]" chars in the filenames.
2) It is not recursing subdirectories it only tries to change the name of it.
See below...
# sh test
mv: `23-Mar-2004_120109[1].tar.gz' and `23-Mar-2004_120109[1].tar.gz' are the same file
mv: `backup_utils.txt' and `backup_utils.txt' are the same file
mv: cannot move `cups-pdf' to a subdirectory of itself, `cups-pdf/cups-pdf'
mv: `encryptpdf.exe' and `encryptpdf.exe' are the same file
mv: cannot move `printerdrivers' to a subdirectory of itself, `printerdrivers/printerdrivers'
mv: `QCS_A2LA_Request.doc' and `QCS_A2LA_Request.doc' are the same file
mv: `remove_illegals.txt' and `remove_illegals.txt' are the same file
mv: `test' and `test' are the same file
mv: `western_web.zip' and `western_web.zip' are the same file
The part about a name with brackets ( [ ] ) in it can be solved but it creates yet another problem as the period ( . ) before the file extension is also in the same class as the brackets. That is they both are [[unct:]]
I also had very little luck with the recursive problem.
Code:
#!/bin/bash
#Note: those smileys don't belong there. It is alnum punct
for i in *; do
echo $i | grep -e '[[:alnum:]][[:punct:]]' | \
mv $i `echo $i | sed 's/[[:punct:]]/_/g'`
done
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.