Remove spaces between file names

Hi All,

I have spaces in between file names.

"Material Header.txt"
"Customer Header.txt"
"Vendor Header.txt"

And how can I remove spaces between file names like below

MaterialHeader.txt
CustomerHeader.txt
VendorHeader.txt

Thanks
Srimitta

use tr,sed or awk command

echo "Material Header.txt"|tr -d ' '
echo "Material Header.txt"|sed 's/ //g'
echo "Material Header.txt"|awk '/ /{gsub(" ","")}{print}'

Thanks Vidyadhar for your reply,

Great, but how to rename all files "with spaces" to "withoutspaces".

Thanks
Srimitta

This trick is working fine,

cp 'Material Header.txt' `ls 'Material Header.txt' | tr -d ' '

But when I try this in loop it doesn't work.

for file in $(ls ' ')
do
echo "$file"
cp "$file" `"$file" tr -d ' '`
done

echo "$file" is returning file name in two parts like below
Material
Header.txt

Any idea how to pass file name to cp without breaking.

The problem with your code is that the shell uses whitespace to delimit words.

Suppose you have a file named "two words", and you write a command like "cp two words" - how is the shell supposed to know wether you want the file "two" copied to "words" or if you are talking about the file "two words" and the second argument is missing?

The same is true for the for-loop, which passes one argument at a time to the content of the loop - and "one argument" is "one word", because this is where the stream the for-loop works on was split at.

So, here is a script which relies on exactly this mechanism:

#!/usr/bin/ksh

typeset oldfile=""
typeset newfile=""

# the grep filters for filenames with spaces only:
ls -1 | grep "[^ ] [^ ]" | while read oldfile ; do
     newfile="$( print - $oldfile | tr -d ' ')"
     print - "mv \"${oldfile}\" \"${newfile}\"" # just display, next line is working
     # mv "$oldfile" "$newfile"
done

By the way: do not use for-loops to process lists of unknown length, like a directory listing. If the list grows too long it will exceed your maximum line length (see syslimits.h) and your code will break. Using a while-loop removes this risk.

I hope this helps.

bakunin

Thanks bakunin,

Great it's working, this is what I was trying to do.

srimitta

Hi bakunin,

Your script works great with spaces in file names, but I have some files Apostrophe between file names like "BOM Header's.txt".

Any help in modifying your script to remove Apostrophe within file names.

Thanks
srimitta

No problem, but I am going to move this thread to "Shell Programming and Scripting" as it is not really AIX-related.

At first you have to change the filter to find also the files with apostrophes in their names. In the following, the first line is the original, the second line into what you should change it:

ls -1 | grep "[^ ] [^ ]" | while read oldfile ; do
ls -1 | grep "[^ '] [^ ']" | while read oldfile ; do

Second you have to change the replacement mechanism itself: the line where from the old filename the new one is derived. As this starts to get more complex we change from the simple "tr" to "sed:

newfile="$( print - $oldfile | tr -d ' ')"
newfile="$( print - $oldfile | sed 's/\'//g;s/ //g')"

Ready - that should do it.

I hope this helps.

bakunin

Another approach with awk:

ls | awk '
{f=$0; gsub("[^A-Za-z0-9.]", "")}
f != $0 { system("mv " f " " $0) }'

First we store the original filename in the variable f and remove the characters, not defined in the class, from the current line (filename). Then we compare the the current line with the original filename and move the file if the name is changed.

Regards

Thanks bakunin,

It's working with a small change, replaced single qoutes to double qoutes.

Hello Srimitta,

You can use the same script given by bacunin and replace the line

" newfile="$( print - $oldfile | tr -d ' ')" as

" newfile="$( print - $oldfile | tr -d ' '| tr -d ''')" "