LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   sed command to replace file extension (https://www.linuxquestions.org/questions/linux-newbie-8/sed-command-to-replace-file-extension-774606/)

leighya 12-09-2009 08:34 PM

sed command to replace file extension
 
I understand how to use a variable in a sed command, but I can't get the output into a variable.


FILE=readme.txt
now i want to remove the extension of filename
so file woud be:
FILE=readme

my script:
NFILE=`echo $FILE | sed 's/.txt//'`
mv ../out/$FILE ../out/$NFILE
FILE=$NFILE


now when i run my script. i get this unknown character extensions in my new file(NFILE). Can someone help me with this.

Thanks
-newbie

ghostdog74 12-09-2009 08:40 PM

you don't need sed to remove file extension
Code:

$ filename="a.txt"
$ echo ${filename%.*}
a


leighya 12-09-2009 08:51 PM

Quote:

Originally Posted by ghostdog74 (Post 3786082)
you don't need sed to remove file extension
Code:

$ filename="a.txt"
$ echo ${filename%.*}
a



how do i do this

echo Renaming $FILE
NFILE= echo ${filename%.*}
mv ../out/$FILE ../out/$NFILE
FILE=$NFILE

I'm really sorry for this simple question.

ghostdog74 12-09-2009 08:53 PM

Code:

NFILE=${filename%.*}

leighya 12-09-2009 09:16 PM

Quote:

Originally Posted by ghostdog74 (Post 3786088)
Code:

NFILE=${filename%.*}

Thanks!this works.but i seem to get a little rectangle character in my new file.
becomes: readme[]

and if i put a new file extension to this file,this character still doesn't disappear.
e.g: readme.enc[]

chrism01 12-09-2009 09:20 PM

Code:

fullname="a.txt"
fname=$(echo $fullname|cut -d'.' -f1)
newname=${fname}.dat


ghostdog74 12-09-2009 10:22 PM

Quote:

Originally Posted by leighya (Post 3786103)
Thanks!this works.but i seem to get a little rectangle character in my new file.
becomes: readme[]

and if i put a new file extension to this file,this character still doesn't disappear.
e.g: readme.enc[]

this should not happen. what is your actual file name? if it is just readme.txt, you would only get "readme" and nothing else.

centos82 12-09-2009 11:27 PM

I am going to agree with ghostdog. There is some hidden character in your filename.

Try navigating to the directory your file is in.

Run "ls -l > myls"
Then "cat -vet myls"

This will show you any hidden characters in your file. See if there is something between readme and your ".". I'll bet there is.

Also, one thing to note about you sed command. It should work but the . in sed is a wildcard so if your file was named readmeAtxt your sed command would change that to readme even though it was not a .txt file because the wildcard matches to the "A". The proper sed is sed 's/\.txt$//' The "\" says ignore the . as a wildcard and treat it as a literal . The $ which could be considered optional says the .txt should occur at the end of the string. If you are dealing with files that have different extensions though, the script is mutch better written with the awk or cut command.

echo $STRING | cut -d. -f1
or
echo $STRING | awk -F. '{print $1}'

leighya 12-10-2009 01:21 AM

Quote:

Originally Posted by centos82 (Post 3786187)
I am going to agree with ghostdog. There is some hidden character in your filename.

Try navigating to the directory your file is in.

Run "ls -l > myls"
Then "cat -vet myls"

This will show you any hidden characters in your file. See if there is something between readme and your ".". I'll bet there is.

Also, one thing to note about you sed command. It should work but the . in sed is a wildcard so if your file was named readmeAtxt your sed command would change that to readme even though it was not a .txt file because the wildcard matches to the "A". The proper sed is sed 's/\.txt$//' The "\" says ignore the . as a wildcard and treat it as a literal . The $ which could be considered optional says the .txt should occur at the end of the string. If you are dealing with files that have different extensions though, the script is mutch better written with the awk or cut command.

echo $STRING | cut -d. -f1
or
echo $STRING | awk -F. '{print $1}'




Thanks for the explanation. I used this script to get rid of the file extension

$(echo $filename|cut -d'.' -f1)


But still the unknown character is there.
Now when i tried to look at the current directory of the file with the unknown character(rectangle thingy)..it turned out to be a \r char. like this: readme\r

catkin 12-10-2009 02:11 AM

Quote:

Originally Posted by leighya (Post 3786279)
Now when i tried to look at the current directory of the file with the unknown character(rectangle thingy)..it turned out to be a \r char. like this: readme\r

If you have only one such file beginning with readme you can fix it manually with
Code:

mv readme* readme
Here's how I reproduced the problem and fixed it
Code:

c:~/d/tmp$ x=$'readme\r'
c:~/d/tmp$ touch "$x"
c:~/d/tmp$ ls readme*
readme?
c:~/d/tmp$ mv readme* readme
c:~/d/tmp$ ls readme*
readme


leighya 12-10-2009 02:26 AM

Quote:

Originally Posted by catkin (Post 3786321)
If you have only one such file beginning with readme you can fix it manually with
Code:

mv readme* readme
Here's how I reproduced the problem and fixed it
Code:

c:~/d/tmp$ x=$'readme\r'
c:~/d/tmp$ touch "$x"
c:~/d/tmp$ ls readme*
readme?
c:~/d/tmp$ mv readme* readme
c:~/d/tmp$ ls readme*
readme



i have multiple files to read and rename.
i used $FILE for the filename

chrism01 12-10-2009 05:07 PM

You can add a loop to my code
Code:

for fullname in $(cat filelist.txt)
do
    fname=$(echo $fullname|cut -d'.' -f1)
    newname=${fname}.dat
done

for filenames that have bad char(s) at the end, you'll need string manipulation fns http://tldp.org/LDP/abs/html/string-manipulation.html to remove them.

ghostdog74 12-10-2009 06:49 PM

Quote:

Originally Posted by chrism01 (Post 3787119)
You can add a loop to my code
Code:

for fullname in $(cat filelist.txt)
do
    fname=$(echo $fullname|cut -d'.' -f1)
    newname=${fname}.dat
done

for filenames that have bad char(s) at the end, you'll need string manipulation fns http://tldp.org/LDP/abs/html/string-manipulation.html to remove them.

breaks on files with spaces... using cat + for loop like that is bad. Either have to change IFS or use a while read loop. Also, with shell, no need to use external command. Its faster that way
Code:

while read -r fullname
do
    IFS="."
    set -- $fullname
    fname=$1
    echo $fname
    # to get rid of bad chars
    echo ${fname//[^[:print:]]/}
done <"file"


ArfaSmif 12-10-2009 08:43 PM

Another simple way to do this is to use the command "basename"
For example:-

$ basename filename.txt .txt

will give you :-

filename

ghostdog74 12-10-2009 08:51 PM

Quote:

Originally Posted by ArfaSmif (Post 3787248)
Another simple way to do this is to use the command "basename"
For example:-

$ basename filename.txt .txt

will give you :-

filename

basename works on one file and AFAIK does not support wildcard (if it does, correct me). To work on multiple files , effectively a loop is still required. In that case, its the same as calling external command for each file.

ArfaSmif 12-10-2009 09:19 PM

Quote:

Originally Posted by ghostdog74 (Post 3787258)
basename works on one file and AFAIK does not support wildcard (if it does, correct me). To work on multiple files , effectively a loop is still required. In that case, its the same as calling external command for each file.

Just giving another option

Pampano 04-21-2012 04:34 PM

Kinda have a similar question and found this thread. What if I had many files but needed to change the extensions of them and they all have different extensions.
For example, if I were to use an sed command to change the file "batman.CPP" to be "batman.cpp"
And I also have a file "kingsandqueens.dat" and I need it to be "kingsandqueens.backup"


I need a shell script that will do this for me if I were to execute the program as ./chExt1.sh 'cpp' 'batman.CPP'
or ./chExt1.sh 'backup' 'kingsandqueens.dat'

Thanks for any help with this.

ArfaSmif 04-21-2012 08:01 PM

Quote:

Originally Posted by ghostdog74 (Post 3787258)
basename works on one file and AFAIK does not support wildcard (if it does, correct me). To work on multiple files , effectively a loop is still required. In that case, its the same as calling external command for each file.

True ghostdog74. I was merely giving an example of how to remove the file extension. Of course this would have to be used in a loop to modify a whole list of filenames.

David the H. 04-22-2012 03:20 AM

1)
To those who haven't noticed, this is a 3 year old thread that has been reopened. It's usually a good idea to not post to old threads unless you specifically have something important to add to the previous discussion. New questions should be made in new threads, perhaps with a referral to the old one if relevant.

2)
Please use [code][/code] tags around your code and data, to preserve formatting and to improve readability. Please do not use quote tags, colors, or other fancy formatting.

3)
When you post, please give us all the relevant details about what you are trying to do. What platform are you using, where are you getting your data, what format is it in, etc.

For example, the old discussion focused on the the occurrence of '\r' in the string. You'll generally only see that as the result of dos-style line endings when operating on files written in Windows. So I suspect the filenames were taken from a windows-created text file, rather than directly. A simple conversion of the file first, or stripping off the last character, would fix that.

4)
For pampano, there are many string manipulations that can be done with shell built-in commands, so probably you won't need to call on sed or another external command.

parameter substitution
string manipulation

And again, you need to define your requirements clearly. Do you just need to lowercase the whole variable? Or ensure that only the extension is lowercase? To use recent bash for that:

Code:

filename='Foobar.TXT'

echo "${filename,,}"                #lowercases the entire filename

ext=${filename##*.}                #grabs the extension from the filename

echo "${filename%.*}.${ext,,}"        #echos the filename without extension,
                                #plus lowercased extension.

As for changing the extension, All you need to know has been presented already:

Code:

filename='kingsandqueens.dat'
echo "${filename%.*}.backup"



All times are GMT -5. The time now is 10:44 PM.