LinuxQuestions.org
Visit the LQ Articles and Editorials section
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 05-12-2004, 02:54 PM   #1
Ziv
LQ Newbie
 
Registered: May 2004
Location: WA
Distribution: RedHat 7.3/9/ES
Posts: 13

Rep: Reputation: 0
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.

Thank you,
Ziv
 
Old 05-12-2004, 03:29 PM   #2
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
Quote:
Is there a direct way to update the name associated with an inode number, without using mv?
Why not mv?
 
Old 05-12-2004, 03:55 PM   #3
Muzzy
Member
 
Registered: Mar 2004
Location: Denmark
Distribution: Gentoo, Slackware
Posts: 333

Rep: Reputation: 30
Replacing with underscores:

filename='test=example+file?'
echo $filename
echo $filename | sed 's/[+{;"\\=?~()<>&*|$ ]/_/g'

I don't understand why you don't want to use mv either!
 
Old 05-12-2004, 04:16 PM   #4
Ziv
LQ Newbie
 
Registered: May 2004
Location: WA
Distribution: RedHat 7.3/9/ES
Posts: 13

Original Poster
Rep: Reputation: 0
I didn't know if it would work...

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.

mv is fine, but it seems that I will need to do it by referring to it's inode number.

Am I right about this?

Ziv
 
Old 05-12-2004, 04:24 PM   #5
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,688
Blog Entries: 54

Rep: Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956
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; }
# retScrubbedString "${filename}"
A__1__Z
 
Old 05-12-2004, 05:09 PM   #6
Muzzy
Member
 
Registered: Mar 2004
Location: Denmark
Distribution: Gentoo, Slackware
Posts: 333

Rep: Reputation: 30
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'

Last edited by Muzzy; 05-12-2004 at 05:20 PM.
 
Old 05-12-2004, 06:15 PM   #7
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,688
Blog Entries: 54

Rep: Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956Reputation: 2956
Tried your script, actually it outputs on my computer:
A___012_Z

Depends on the charset you're using I guess?


How about this, which I think has the same effect as your script
Yeah, that works fine. That's the *easy* way tho :-]
 
Old 06-17-2004, 10:28 PM   #8
Ziv
LQ Newbie
 
Registered: May 2004
Location: WA
Distribution: RedHat 7.3/9/ES
Posts: 13

Original Poster
Rep: Reputation: 0
How can I use the find command to execute a mv?

I like the sed command that is above, but I am having problems tying that into a mv command that will change the old filename into a new one.

I was trying something like this...

find . -name '*[;"\\=?()<>&*|$]*' -exec $badname= '{}' \; | $filname= sed 's/[;"\\=?()<>&*|$]/_/g' | mv $badname $filename

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.

Any help is appreciated...

ZIv
 
Old 06-17-2004, 11:37 PM   #9
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 56
How about something like this....

Code:
#!/bin/bash

for i in *; do
echo $i | grep -e '*[~!#%^+;"\\=?()<>&*|$]*' | \
mv $i `echo $i | sed 's/[~!#%^+;"\\=?()<>&*|$]/_/g'`
done
 
Old 06-18-2004, 01:18 AM   #10
Ziv
LQ Newbie
 
Registered: May 2004
Location: WA
Distribution: RedHat 7.3/9/ES
Posts: 13

Original Poster
Rep: Reputation: 0
Slight Problem...

There is a slight problem with that solution...

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?

Thank you for the reply,
Ziv
 
Old 06-18-2004, 01:30 AM   #11
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 56
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
 
Old 06-18-2004, 01:33 AM   #12
Ziv
LQ Newbie
 
Registered: May 2004
Location: WA
Distribution: RedHat 7.3/9/ES
Posts: 13

Original Poster
Rep: Reputation: 0
Quote:
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

What is the output like when you run it?

Ziv
 
Old 06-18-2004, 01:38 AM   #13
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 56
Oh, I see what you are saying.

Quote:
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.
 
Old 06-18-2004, 01:48 AM   #14
Ziv
LQ Newbie
 
Registered: May 2004
Location: WA
Distribution: RedHat 7.3/9/ES
Posts: 13

Original Poster
Rep: Reputation: 0
Looks like it is working good...

Two last things that need ironed out...

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


Any ideas on these problems?

Ziv
 
Old 06-18-2004, 12:12 PM   #15
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 56
Well, I hit a wall on this one.

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

Last edited by homey; 06-18-2004 at 12:32 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash Script Array index value Kedelfor Programming 10 04-29-2009 05:37 AM
iNode number, how does it change? saudoi Solaris / OpenSolaris 4 05-22-2005 05:38 AM
Getting the first part of a filename in a BASH script trevelluk Programming 3 02-15-2005 02:06 AM
What can change an inode number? nc101 Linux - General 2 01-03-2005 11:29 AM
bash script - incrementing a filename in a script tslinux Programming 10 08-06-2003 12:58 AM


All times are GMT -5. The time now is 07:03 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration