The UNIX and Linux Forums  
Hello and Welcome from United States to the UNIX and Linux Forums! Thank You for Visiting and Joining Our Global Community.

Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
.
google unix.com



Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts and shell scripting languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Script to tar up old log files aojmoj Shell Programming and Scripting 5 02-17-2008 10:57 AM
Script lines of a Log Files Nysif Steve Shell Programming and Scripting 2 08-30-2007 10:55 AM
How to process the files using .tar.gz files in script bmkreddy Shell Programming and Scripting 3 05-04-2007 02:00 PM
bash script working for small size files but not for big size files. davidpreml Shell Programming and Scripting 1 11-01-2006 11:06 AM
Rename Files with a script ? yoveln OS X (Apple) 1 02-08-2004 12:45 PM

Closed Thread
English Japanese Spanish French German Portuguese Italian Dutch Swedish Russian Norwegian Hungarian Hebrew Danish Bulgarian Greek Powered by Powered by Google
 
LinkBack Thread Tools Search this Thread Rate Thread Display Modes
  #1 (permalink)  
Old 09-22-2008
Keith Daniels Keith Daniels is offline
Registered User
  
 

Join Date: Sep 2008
Posts: 6
cp files containing \ from a script

I am using a sh shell to try and create a script to remove backslashes (and other characters) from filenames.

At the end of the script I need to copy the original filename (with the backslash) to the new file name.

So far I have not been able to figure out how to do that from inside a for loop.


Example:

On the command line or inside the script, I can use this "exact" command to copy the file junk/junk.txt to junkjunk.txt

cp junk\\junk.txt junkjunk.txt

and it works perfectly.


But I need to use a variable or perhaps command substitution to represent the original filename inside the script, like this:

cp "$oldfilename" $newfilename

Even though I can create a variable, that echo "$oldfilename" shows contains junk\\junk.txt -- I can not get the cp command to work.

I have tried many variations of this using multiple backslashes with no success.

Is this even possible?

Thanks in advance.....
  #2 (permalink)  
Old 09-22-2008
amsct amsct is offline
Registered User
  
 

Join Date: Aug 2008
Location: Amsterdam, The Netherlands
Posts: 33
Code:
oldname='junk\\junk.txt'
newname=junkjunk.txt
cp $oldname $newname
  #3 (permalink)  
Old 09-22-2008
Keith Daniels Keith Daniels is offline
Registered User
  
 

Join Date: Sep 2008
Posts: 6
Thanks for the reply amsct. For a while I thougt this was the answer to my problem

But your code below, is just a variation of typing the text of the file name into the script by hand. It does work for turning the hand typed text in to a variable that cp can read and I think it will be useful in the future for things that are defaults that need to be run the same as they would be from the command line.... but, it does not solve my problem. I did not know that single quotes used like that, made a diifference in the output and I will play with it in the future and look for other uses, so thanks for the information.

Quote:
Originally Posted by amsct View Post
Code:
oldname='junk\\junk.txt'
newname=junkjunk.txt
cp $oldname $newname
The processing flow of the "problem" is this:

1 - I read the contents of the directory into a variable.
2 - That variable is read by the for loop.
3 - The individual file names are provided as a variable by the for loop one at a time.
4 - I use that variable to cp the old file name to the new.

In other words my starting point for accessing the original file name, is always a variable returned by the for loop.

Somehow I need to turn that variable ( or a processed version of it ) into a version that will work with cp from inside the script.

Perhaps there are some changes I can make in the loop or there are other ways of reading in the file names to the loop.

But note that a for * type of loop, directly accesing the directory, will not work because the file names contain illegal characters and spaces.

Any ideas?
  #4 (permalink)  
Old 09-22-2008
danmero danmero is offline Forum Advisor  
  
 

Join Date: Nov 2007
Location: 45.48-73.63
Posts: 1,421
Use parameter expansion and escape the backslash:
Code:
oldname='junk\\junk.txt'
newname=junkjunk.txt
cp ${oldname/\\/\\\\} $newname
  #5 (permalink)  
Old 09-23-2008
Keith Daniels Keith Daniels is offline
Registered User
  
 

Join Date: Sep 2008
Posts: 6
Results of testing the two suggestions presented

This is the results of testing the two suggestions presented so far.

(I hope this is not a double post. I posted this earlier but it never appeared in the forum...)

As long as the exact block is entered into the script, all of the methods below will copy the old file (with the backslash) to the new file.

NONE of them will work when the oldname variable is read from the directory or passed from the "for loop" -- even when oldname is EXACTLY the same as any of the text assigned to oldname variables below.



oldname=junk\\junk.txt
newname=junkjunk.txt
cp $oldname $newname

The the above works WITHOUT quotes OR with
double quotes ONLY, on either or both variables


oldname="junk\junk.txt"
newname=junkjunk.txt
cp ${oldname/\/\\} $newname

oldname="junk\junk.txt"
newname=junkjunk.txt
cp $oldname $newname

In the TWO examples above, oldname MUST be quoted, with single OR double quotes,
AND newname MAY or MAY NOT be quoted with single OR double quotes.

-----------

Does this make any sense to anyone. I can not see how the bash shell could distinguish between a variable created inside the script, from data inside the script AND a variable created inside the script from identical text passed in from outside the script.


The only thing I can think of is that I am reading in the filenames to the variable through a pipe and that starts a sub-process which might fold, spindle or mutilate the variable in some manner that causes this problem.

I am leaving the country for a week in about 36 hours. If I have time I will rework the script to where the file list is imported without using a pipe and see if that changes how the variables react.

If anyone has any other ideas I would appreciate hearing them.

Thanks
  #6 (permalink)  
Old 10-08-2008
Keith Daniels Keith Daniels is offline
Registered User
  
 

Join Date: Sep 2008
Posts: 6
Problem's solution

I never did truly understand "exactly" what it was about how I was using variables that was the problem but I found a work around, so to speak.

First if you want to use a variable to hold a "bad" file name, or one with unusual characters in it, to be used with the cp command -- then process the filename the minimum amount possible. I was processing the file name to create a new name, then I had to process it some more to undo the first processing so I could get the original name back. Bad idea, something happened to the filename while doing all that processing and I could never get it back to exactly what it was before... So I set out to minimize the processing of the filename to be used in the variable used to copy the old filename to the new filename.

Second, bash does its own processing of special characters and spaces when the cp command is run. Do not try to help it by adding escape characters (backslashes) to the variable. You have to deliver the name to the variable "exactly" as it appears when you use ls to display it. Then if the variable is quoted with double quotes, then bash can properly process it -- no matter what characters are in the file name.

Even though you can type the filename in by hand and add backslashes to the name and when you run the cp command from the script, it will work -- that ability will not transfer to a variable. Putting that same text with backslashes into a variable does not work because the variable does some processing "before or as" it expands the variable when the cp command is run. That "extra" processing produces something that is different than what was put in the variable, usually it adds backslashes and when it does, it does not match the "real" filename and can not copy it to the new filename.

Here is how I was originally processing the filenames. I was creating a list of filenames and storing them as a variable. Because the variable "fed" a for loop, I had to remove any spaces before I used the variable (for loops will not work with spaces in the filenames). I created the "filename list" variable and converted the spaces to % at the same time. I then separated the filenames into the basename and extension and stored them in variables. When I finished I reassembled this to get the original filename's basename and extension and removed the %s that I had inserted previously

This was too much processing. I ignored the KISS rule. The final cure was use the entire original filename with the % added -- as provided by the for loop -- instead of breaking it into basename and extension and having to reassemble all that back into the original file name. This allowed me to use the original filename with no processing other than removing the % symbol which I did at the same time I reassigned it to the final variable used by the cp command. Then all I had to do was quote the variable and everything worked.

My filename repair script works perfectly now and can repair filenames with leading and trailing spaces, backslashes, single quotes and any other characters that I have tried so far except the % symbol. There are two problems with % in the filename. When they are assigned to the variable storing the filenames bash turned % into %%, then the script turned all spaces into % and things went downhill from there. I decided to leave things alone and not try to process files with % in them, (files with % in them are very rare anyway).

I hope this makes sense, and can help someone in the future.

Thanks for everyone's help.
  #7 (permalink)  
Old 10-08-2008
dddkiran dddkiran is offline
Registered User
  
 

Join Date: Oct 2008
Posts: 25
Hi! you can try this:

find 'pwd' -name "*.*" | awk -F'\' -v var="" '{while(i==NF){var= print $var$i;} print "cp "$0" "$var""}'

This is just an idea to say you can do something like this, Please feel free to edit it if it is not working as per your requirement.
Closed Thread

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT -4. The time now is 10:04 PM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited. Language Translations Powered by .
vBCredits v1.4 Copyright ©2007 - 2008, PixelFX Studios
The UNIX and Linux Forums Content Copyright ©1993-2009. All Rights Reserved.Ad Management by RedTyger

Content Relevant URLs by vBSEO 3.2.0