Change file extension, but keep original file - bash

I have a set of .txt files I want to change the extension of, but keeping the original.
I'm trying to cp each file to a "temp", then mv that "temp" to a new file with a new extension.
for file in $#; do
cp ${file} temp; mv temp ${file}.fas
done
I can't find out why it's not working, but nothing happens. I'm new to bash, so any help appreciated.

Read about substring replacement in bash variables.
This will copy all files like foo.txt to foo.fas:
for file in *.txt; do
cp "$file" "${file/%.txt/.fas}"
done

Related

Rename a file when I don't know its name - shell script

I am trying to rename a file which is the only file in a directory.
It is a podcast download which changes name each day so I don't know what it is called but it always ends in .MP3
I want to rename it to news.mp3
I have tried the following based on another solution on this site but it appends the news to the file
#!/bin/sh
for file in *.MP3; do
mv "$file" "${file/.MP3/news.mp3}"
done
If it's the only file in the directory you can just write the following command:
mv directory_name/* directory_name/news.mp3
In case there are few files or if dir is empty:
shopt -s nullglob
src="/path/to/dir/with/files"
dst="/destanation/folder"
i=1
cd "$src"
for f in *; do
mv "$f" "$dst/new_name_$((i++))"
done

Deleting specific files in a directory using bash

I have a txt file with a list of files (approximately 500) for example:
file_0_hard.msOut
file_1_hard.msOut
file_10_hard.msOut
.
.
.
file_1000_hard.msOut
I want to delete all those files whose name is not in the txt file. All of these files are in the same directory. How can I do this using bash where I read the text file and then delete all those files in the directory that are not in the text file. Help would be appreciated.
Along the lines of user1934428
There is something to say for this solution. But since we have linux at our disposal with a strong filesystem in use I hope. we can make hardlinks; The only requirement for that the destination is on the same filesystem.
So along those lines:
make a directory to store the files you want to keep.
hardlink (ln {file} {target}) ; as this does not cost extra disk space, it only stores the inode number in the new directory file.
remove all files
move the files back from their origin.
And actually this would be about the same as:
mv {files} {save spot}
remove all files
mv {save spot}/{files} back
Which does pretty much the same thing. Then again; it is a nice way to learn about the power of a hardlink.
you may try this :
cd path/dir
for f in *; do
if ! grep -Fxq "$f" pathToFile/file.txt; then
rm -r "$f"
else
printf "exists-- %s \n" ${f}
fi
done
In case you are wondering (as I did) what -Fxq means in plain English:
F: Affects how PATTERN is interpreted (fixed string instead of a regex)
x: Match whole line
q: Shhhhh... minimal printing
Assuming the directory in question is mydir
set -e
cd mydir
tmpdir=/tmp/x$$ # adapt this to your taste
mv $(<list.txt) $tmpdir
cd ..
rm -r mydir
mkdir mydir
mv $tmpdir/* mydir
rm -r $tmpdir
Basically, instead to delete those files you want to keep, you safe them, then delete everything, and then restore them. For your case, this is probably faster than doing the other way around.
UPDATE:
As Michiel commented, it is advisable that you place your tmpdir in the same file system as mydir.

Unable to rename and move files from one location to another

I need to add prefix C_ and then move files from tmp location to target location.
Here is the script
I am not allowed to place script in current directory.
for tmpfile in /home/asmita/tmp
do
mv "$tmpfile" "C_${tmpfile}"
mv "C_${tmpfile}" /home/tgasmita
done
When I try moving prefixed files I get error C_/home/asmita/tmp/xyz.txt not found. as entire path is stored in tmpfile variable.
Change your code to use the basename and the dirname command to get the filename and the directory name. Use these to combine the values and get the new path.
for tmpfile in /home/asmita/tmp
do
DIRPATH=$(dirname "${tmpfile}")
FILENAME=$(basename "${tmpfile}")
mv "$tmpfile" "${DIRPATH}C_${FILENAME}"
mv "${DIRPATH}C_${FILENAME}" /home/tgasmita
done
There are many ways to do this. First let me fix your script.
1.In below code make sure that you are passing only filename not the full path. Below script is valid only if know the FILENAME
#!/bin/sh
for tmpfile in /home/asmita/tmp
do
mv "{tmpfile}/filename.txt" "/home/tgasmita/C_filename.txt"
done
2.If you do not know file name and you want to rename and move .txt files to another folder then you might like below script.
#!/bin/sh
lines=`find /home/asmita/tmp -name "*.txt" -printf "%f\n";`
for i in ${lines[#]}
do
mv "/home/asmita/tmp/${i}" "/home/tgasmita/C_${i}"
done
Please note that I m looking for only text file in source folder(/home/asmita/tmp
) You can change .txt to other extension according to requirement. If you want to move and rename all files from source folder then just replace "*.txt" to ".*" from second line.

mv using filename expansion operation caused files to disappear

I have a bunch of files named
index.html.1
index.html.2
...
I tried to write a bash script to fix all of their extensions
for file in *.html.*
do
mv "$file" "${file%.html.*}.jpg"
done
which made all of the files disappear.
What have I done?!
You have moved each index.html file, one at a time, to the same target filename. Unfortunately all but the last has now been overwritten.
touch index.html.{1,2,3,4,5}
for file in *.html.*; do echo mv "$file" "${file%.html.*}.jpg"; done
Output
mv index.html.1 index.jpg
mv index.html.2 index.jpg
mv index.html.3 index.jpg
mv index.html.4 index.jpg
mv index.html.5 index.jpg

Rename Two files in the Same Folder

Files
events-number1.10a.pdf
Result
events-number1.10a.docx.pdf
Ideal
events-number1.10a.pdf
events-number1.10a.docx.pdf
A simple rename command will do the job.
rename 's/(?=\.pdf$)/.docx/' *.pdf
You can try this simple bash script
#!/bin/bash
for file in *.pdf
do
new_file=$(echo "$file" | sed -r 's/(.*)(\.pdf)/\1.docx\2/')
mv $file $new_file
done
Output:
events-number1.index10a.docx.pdf
events-number1.index10b.docx.pdf
events-number1.index10c.docx.pdf
events-number2.index10a.docx.pdf
events-number2.index10b.docx.pdf
events-number2.index10c.docx.pdf
If you want copy the file using cp command instead of mv command
cp $file $new_file
So your existing files won't change.
Explanation :
Passing all the log file to for loop ,then split the file name to your expected result for using sed command and stored in one variable . Then mv the old file to new file that mean your expected file .

Resources