Can I use sed to rename files with a "running count"? - linux

I have a directory full of pictures. Lets say
/usr/pics/foo
/usr/pics/duckface.jpg
usr/pics/bar.bmp
...
I'd like to go through and rename them to
/usr/pics/pic1
/usr/pics/pic2
/usr/pics/pic3
...
Doesn't have to be sed anything I can run from a bash script will be fine. I think I can handle the regex I just don't know what to replace with.

I assume that all files in the directory are images and you want to rename all of them without worrying of extensions or file types. Then try:
for f in /usr/pics/*; do ((i++)); mv "$f" "${f%/*}/pic${i}"; done

Related

Change - to _ in file names

I have files named this way
A-1
B-3
C-5
U-8
A-2
... and so on.
I want to change the name of all these files to this because the software I want to use didn't accept files named that way and I think it's because of -.
A_1
B_3
C_5
U_8
A_2
So basically I just want to change - by _ in all the files, using for loop or something.
this command should work for you
for FILE in *; do NFILE=$(echo "$FILE" | sed s/-/_/g); mv "$FILE" "$NFILE"; done
The forloop grabs all the files in the directory, you could add something like *.png to filter the files. In this loop the filename is echoed and piped to sed. Sed is a handy tool which can do all sorts of things, but we use it to change the - to a _ by the syntax: s/find/replace/g. After this we use this new variable to move the existing file to the new name a.k.a. renaming it.
Let me know if you need any more help!
Edit:
As Shawn mentioned below, if you are using bash or zsh you can use the building function and don't need sed. This command would look like this:
for FILE in *; do mv "$FILE" "${FILE//-/_}"; done
Really nice and compact, Thanks Shawn!

rename all files after extension

Is it possible to write a script to rename all files after the extension?
Example in the folder, there are :
hello.txt-123ahr
bye.txt-56athe
test.txt-98hg12
I want the output:
hello.txt
bye.txt
test.txt
If you just want to remove everything from the dash forwards, you can use Parameter expansion:
#!/bin/bash
for file in *.txt-* ; do
mv "$file" "${file%-*}"
done
Where ${file%-*} means "remove from $file everytning from the last dash". If you want to start from the first dash, use %%.
Note that you might overwrite some files if their leading parts are equivalent, e.g. hello.txt-123abc and hello.txt-456xyz.

Sort files according to their filetype

After an HD problem and some work, I have a bunch of files with names like "f1234", "f1235", etc.
My goal is to sort this files according to their filetype. For example, I want to move all the PDF files in the "pdfs" directory.
For one file, I can do : "file f1234", and if it's a PDF, I can "mv f1234 pdfs/". But I have thousands of file... Can you help me with a bash or zsh command for sort all the PDF in one pass ? Thanks
The hard part here is reliably turning the output of file into a directory name. I think probably the best candidate for that is the mime-type of the file rather than the human readable output of file. I'd use something like:
mkdir sorted
for f in f*
do
d=$(file -b --mime-type "$f" | tr / -)
mkdir -p "sorted/$d"
mv "$f" "sorted/$d/"
done
Obviously I'd test that out a bit before running it on your files, but something pretty close to that should work.

linux rename files in bulk using bash script or command line one liner

I have a list of for example 100 files with the naming convention
<date>_<Time>_XYZ.xml.abc
<date>_<Time>_XYZ.xml
<date>_<Time>_XYZ.csv
for example
20140730_025373_XYZ.xml
20140730_015233_XYZ.xml.ab
20140730_015233_XYZ.csv
Now I want to write script which will remove anything between two underscores. for example in the above case
remove 015233 and change 20140730_015233_XYZ.xml.ab to 20140730_XYZ.xml.ab
remove 015233 and change 20140730_015233_XYZ.csv to 20140730_XYZ.csv
I have tried number of various options using rename, cut, mv but I am getting varied results, not the one which I expect.
You could use rename command if you want to rename files present inside the current directory,
rename 's/^([^_]*)_[^_]*(_.*)$/$1$2/g' *
You can use sed:
sed 's/\([^_]*\)_.*_\(.*\)/\1_\2/' files.list
You can also use cut command
cut -d'_' -f1,3 filename
for FILE in *; do mv "$FILE" "${FILE/_*_/_}"; done
And more specific is
for FILE in *.xml *.xml.ab *.csv; do mv "$FILE" "${FILE/_*_/_}"; done
Further:
for FILE in *_*_*.xml *_*_*.xml.ab *_*_*.csv; do mv "$FILE" "${FILE/_*_/_}"; done

Partial File Rename with different file types

Sorry if this is very simple compared to usual questions but I am just starting out. I have some files all with the same start name but of different file types, e.g:
1234.x
1234.y
1234.z
1234_V2.x
1234_V2.y
1234_V2.z
I want to rename the first part of these whilst keeping any ending and file type, e.g:
4321.x
4321.y
4321.z
4321_V2.x etc
I have tried using
mv 1234* 4321*
and
rename 1234* 4321*
But no luck! I have also been through all the other SO articles and although I could use a loop, most depend on the file type being the same.
Thanks in advance
You can use bash substitution:
for file in 1234*
do mv "$file" "4321${file#1234}"
done
OR, replace the do mv with the following
do mv "$file" "${file/1234/4321}"
See more in man bash under EXPANSION section, sub-section Parameter Expansion
Assuming your filenames for 1234 and 4321 i.e constant for all files, you can try this
for fn in `find . -name 1234*`
do
newf=`echo $fn | sed s/1234/4321/`
mv $fn $newfn
done
You can use a shell script, but it's kind of ugly because it will fork a lot, and thus, if you have a lot of files to rename, it will take time.
for f in 1234*; do echo mv $f $(echo $f | sed -e 's/1234/4321/'); done
Otherwize, rename is a good way to do it:
rename 's/1234/4321/' 1234*
Rename expects a regular expression as first parameter, see online documentation
See if it works:
rename "s/1234/4321/" 1234*
command means substitute(because of s) occurances of "1234" with "4321" in files that has name of pattern 1234*
You can also look at here. It is slightly more complicated than your case.

Resources