A program messed up my directory putting a dot "." on the end of some file and directory names. What is the easiest way to remove them?
I have thought of removing the last character but not all the files/dirs have a dot on the end. Also removing all the dots is a problem, this will make the extension useless.
What I need is a rename to change name.of.the.file.ext. to name.of.the.file.ext and name.of.the.dir. to name.of.the.dir
Thanks!
Go over the files with the dot at the end, rename each if possible (i.e. the target file does not exist).
for file in *. ; do
[[ -e ${file%.} ]] || mv "$file" "${file%.}"
done
echo Not renamed: *.
There might be a rename utility on your machine that will let you do
rename 's/\.$//' *.
Check man rename
Related
I have several fastq.gz files in a directory. I want to delete parts of each file name.
Here are the file names:
RES_1448_001_S289_L001_R1_001.fastq.gz
RES_1448_001_S289_L001_R2_001.fastq.gz
RES_1448_012_S300_L001_R1_001.fastq.gz
RES_1448_012_S300_L001_R2_001.fastq.gz
I want to remove S and 3 digits after it. I expect this after removing
RES_1448_001_R1_001.fastq.gz
RES_1448_001_R2_001.fastq.gz
RES_1448_012_R1_001.fastq.gz
RES_1448_012_R2_001.fastq.gz
I asked a similar question before, but was advised to ask a new one to cover the precise requirements I have now.
Old question: Delete part of name of multiple files in Linux
Use rename.
rename 's/S\d{3}_//' *.fastq.gz
Using this bash, regEx would do the trick for you.
#!/bin/bash
for file in *.fastq.gz
do
if [[ $file =~ ^(.*)S([[:digit:]]{3})_L([[:digit:]]{3})_(.*)$ ]]
then
start="${BASH_REMATCH[1]}"
end="${BASH_REMATCH[4]}"
mv -- "$file" "${start}${end}"
fi
done
I would like to append the same string for all of the folders name (to the end) in the root folder.
Based on the below question these code may be useful:
for dir in * ; do mv "${dir}" "${dir/_-_ppfsefs/}" ; done
Batch rename folders
However, these code cuts the unwanted parts. And I want to add a string at the end of folder name.
use mv "${dir}" "${dir}_-_ppfsefs", no slashes.
I'm trying append to word "dicom" to the front of many filenames in a set of folders. The folders all begin with "s" (referred to by "s*" in the script below), and each contain many files (specified by "*" below)--I'd like all of these files to be changed using this bash script. I tried to run this:
for file in /Volumes/USB_AIB/DICOMFunCurrentBatch/MOVr1unzip/s*/*
do
mv $file dicom${file%%}
done
but got thousands of lines of the following error (once for each file within each folder--this is just an example of one of them):
mv: rename /Volumes/USB_AIB/DICOMFunCurrentBatch/MOVr1unzip/s307_1/29217684 to dicom/Volumes/USB_AIB/DICOMFunCurrentBatch/MOVr1unzip/s307_1/29217684: No such file or directory
Any ideas on how to fix it?
I don't you have a valid path as dicom/Volumes/USB_AIB/DICOMFunCurrentBatch/MOVr1unzip/s307_1/, why do you add dicom at the beginning?
maybe you want to append dicom to the end of the $file?
mv "$file" "${file}_dicom"
or something like that.
the following variable expansion ${file%%} is strange because it does nothing:
${parameter%%word} : remove the longest matching suffix pattern.
to move the file into a directory the path should exists, to create the path:
mkdir -p "$(dirname "${newfilename}")"
Maybe what you are trying to do:
for file in /Volumes/USB_AIB/DICOMFunCurrentBatch/MOVr1unzip/s*/*
do
mv "$file" "${file%/*}/dicom${file##*/}"
done
I am very new with linux usage maybe this is my first time so i hope some detailed help please.
I have more than 500 files in multiple directories on my server (Linux) I want to change their extensions to .xml using bash script
I used a lot of codes but none of them work some codes i used :
for file in *.txt
do
mv ${file} ${file/.txt}/.xml
done
or
for file in *.*
do
mv ${file} ${file/.*}/.xml
done
i do not know even if the second one is valid code or not i tried to change the txt extension beacuse the prompt said no such file '.txt'
I hope some good help for that thank you
Explanation
For recursivity you need Bash >=4 and to enable ** (i.e. globstar) ;
First, I use parameter expansion to remove the string .txt, which must be anchored at the end of the filename (%) :
the # anchors the pattern (plain word or glob) to the beginning,
and the % anchors it to the end.
Then I append the new extension .xml
Be extra cautious with filename, you should always quote parameters expansion.
Code
This should do it in Bash (note that I only echothe old/new filename, to actually rename the files, use mv instead of echo) :
shopt -s globstar # enable ** globstar/recursivity
for i in **/*.txt; do
[[ -d "$i" ]] && continue; # skip directories
echo "$i" "${i/%.txt}.xml";
done
If its a matter of a one or two sub-directories, you can use the rename command:
rename .txt .xml *.txt
This will rename all the .txt to .xml files in the directory from which the command is executed.
If all the files are in same directory, it can be done using a single command. For example you want to convert all jpg files to png, go to the related directory location and then use command
rename .jpg .png *
I wanted to rename "file.txt" to "file.jpg.txt", used rename easy peezy:
rename 's/.txt$/.jpg.txt/' *.txt
man rename will tell you everything you need to know.
Got to love Linux, there's a tool for everything :-)
passing command line argument for dir path
#!/bin/sh
cd $1
names_1=`ls`
for file in ${names_1}
do
mv ${file} ${file}.jpg
done
I have been using the rename command to batch rename files. Up to now, I have had files like:
2010.306.18.08.11.0000.BO.ADM..BHZ.SAC
2010.306.18.08.11.0000.BO.AMM..BHZ.SAC
2010.306.18.08.11.0000.BO.ASI..BHE.SAC
2010.306.18.08.11.0000.BO.ASI..BHZ.SAC
and using rename 2010.306.18.08.11.0000.BO. "" * and rename .. _. * I have reduced them to:
ADM_.BHZ.SAC
AMM_.BHZ.SAC
ASI_.BHE.SAC
ASI_.BHZ.SAC
which is exactly what I want. A bit clumsy, I guess, but it works. The problem occurs now that I have files like:
2010.306.18.06.12.8195.TW.MASB..BHE.SAC
2010.306.18.06.14.7695.TW.CHGB..BHN.SAC
2010.306.18.06.24.4195.TW.NNSB..BHZ.SAC
2010.306.18.06.25.0695.TW.SSLB..BHZ.SAC
which exist in the same folder. I have been trying to get the similar results to above using wildcards in the rename command eg. rename 2010.306.18.*.*.*.*. "" but this appends the first appearance of 2010.306.18.*.*.*.*. to the beginning of all the other files - clearly not what I'm after, such that I get:
2010.306.18.06.12.8195.TW.MASB..BHE.SAC
2010.306.18.06.12.8195.TW.MASB..BHE.SAC2010.306.18.06.14.7695.TW.CHGB..BHN.SAC
2010.306.18.06.12.8195.TW.MASB..BHE.SAC2010.306.18.06.24.4195.TW.NNSB..BHZ.SAC
2010.306.18.06.12.8195.TW.MASB..BHE.SAC2010.306.18.06.25.0695.TW.SSLB..BHZ.SAC
I guess I am not understanding a fairly fundamental principal of wildcards here so, can someone please explain why this doesn't work and what I can do to get the desired result (preferably using rename).
N.B.
To clarify, the output wants to be:
ADM_.BHZ.SAC
AMM_.BHZ.SAC
ASI_.BHE.SAC
ASI_.BHZ.SAC
MASB.BHE.SAC
CHGB.BHN.SAC
NNSB.BHZ.SAC
SSLB.BHZ.SAC
You can try this first to see what commands would be executed
for f in *; do echo mv $f `echo $f | sed 's/2010.*.TW.//'` ; done
If it's what you expect, you can remove echo from the command to execute
for f in *; do mv $f `echo $f | sed 's/2010.*.TW.//'` ; done
rename does not allow wildcards in the from and to strings. When you run rename 2010.306.18.*.*.*.*. "" * it is actually your shell which first expands the wildcard and then passes the result of the expansion to rename, hence why it does not work.
Instead of using rename, use a loop as follows:
for file in *
do
tmp="${file##2010*TW.}" # remove the file prefix
mv "$file" "${tmp/../_}" # replace dots with underscore
done