how to delete filename's specific suffix in a dir, in linux [duplicate] - linux

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Extract filename and extension in bash
Linux: remove file extensions for multiple files
For example, A.txt B.txt, I want to rename then to A and B .
How can I do it with shell script? Or other method ? Thanks.

for i in *.txt; do mv "$i" "${i%.txt}"; done

I would use something like:
#!/bin/bash
for file in *.txt
do
echo "$file" "$( echo $file | sed -e 's/\.txt//' )"
done
Of course replace the two above references of ".txt" to whatever file extension you are removing, or, preferably just use $1 (the first passed argument to the script).
Michael G.

for FILE in *.txt ; do mv -i "$FILE" "$(basename "$FILE" .txt)" ; done

Related

Rename file in Linux removing some strings [duplicate]

This question already has answers here:
Rename multiple files based on pattern in Unix
(24 answers)
Closed 8 months ago.
I have a lot of files with this format:
download_agrupocqa_127_1656097965.tar.gz
download_bjxkwris_127_1656097966.tar.gz
download_climpieza_127_1656097965.tar.gz
download_dhermagqu_127_1656097966.tar.gz
Do you know some command to rename all files in a folder to this format?
agrupocqa.tar.gz
bjxkwris.tar.gz
climpieza.tar.gz
dhermagqu.tar.gz
Which means remove: download_ and _127_1656097965
In BASH:
for file in *.tar.gz ; do
suffix="${file#download_}" # this removes download_
prefix="${suffix%%_*.tar.gz}" # this removes everything after underscore
mv "$file" "${prefix}.tar.gz" # this renames the file
done
If you have sed:
for file in *.tar.gz ; do
newname=$(echo "$file" | sed 's/download_\([^_]*\)_[0-9_]*\..*/\1.tar.gz/')
mv "$file" "$newname"
done

For loop in bash [duplicate]

This question already has answers here:
How to loop through a directory recursively to delete files with certain extensions
(16 answers)
BASH: Writing a Script to Recursively Travel a Directory of N Levels
(2 answers)
Closed 4 years ago.
I'm trying to write a bash script that recursively goes through files in a directory, writing the file's name and hexdump to a file. My current script:
#/bin/sh
touch hexdump.txt
for filename in logical/*; do
echo "$filename"
"$filename" >> hexdump.txt
hd /logical/"$filename" >> hexdump.txt
done
The current output is:
logical/*
./hexadecimalExtraction.sh: line 5: logical/*: No such file or directory
hd: /logical/logical/*: No such file or directory
How do i get it to interpret "logical/*" as the list of files within "logical" directory and not the filename itself???
"$filename" >> hexdump.txt
should probably be removed
Otherwise you are trying to run the filename itself.
Also you are looking for files in logical subdirectory in the current directory, but the trying to look in /logical/
You can't recurse with for filename in logical/*. In order to recurse, you have to use find.
To make find visit only files, not directories, use find -type f.
I don't know hd, but you probably want
find tutorials -type f | while read i; do
echo $i >> hexdump.txt
hd $i >> hexdump.txt
done
You're looking for the ** glob operator.
shopt -s globstar nullglob
for filename in logical/**/*; do
echo "$filename"
hd "$filename"
done >> hexdump.txt
filename will contain the full name of the matched files, which already includes the directory logical and any sub directories.

star wildcard in bash [duplicate]

This question already has answers here:
Rename multiple files in shell [duplicate]
(4 answers)
Closed 4 years ago.
I've got a small problem with my bash script. I try to change file name in current directory for whole files with txt extension to text extension. For exampel 1.txt to 1.text
My script looks like this now:
#!/bin/bash
FILES=`ls /home/name/*.txt`
NAME=*.txt
RENAME=*.text
for file in FILES
do
mv $NAME $RENAME
done
i try whole combination with single, double quotes and backticks and I receive errors all the time.
Do you have some ideas how to receive wildcards "*" in bash?
Thanks.
That's not at all how you do that.
#!/bin/bash
shopt -s nullglob
OLD=.txt
NEW=.text
FILES=(/home/name/*"$OLD")
for file in "${FILES[#]}"
do
mv "$file" "${file%$OLD}$NEW}"
done
There are a number of issues with your script. Firstly, you shouldn't run ls and attempt to store its output like that. If you want to iterate through those file, just do it in the loop:
for file in /home/name/*.txt
Now the shell is doing all the work for you, and as a bonus handling any kind of weird filenames that you might have.
In your example you were looping over the literal string "FILES", not the variable, but I guess that was just a typo.
The built-in way to change the filename is to use a parameter expansion to remove the old one, then concatenate with the new one:
old=txt
new=text
for file in /home/name/*"$old"
do
mv "$file" "${file%$old}$new"
done
If it is possible that there are no files matching the glob, then by default, the /home/name/*.txt will not be expanded and your loop will just run once. then you have a couple of options:
use shopt -s nullglob so that /home/name/*.txt expands to null, and the loop is skipped
add an explicit check inside the loop to ensure that $file exists before trying to mv:
for file in /home/name/*"$old"
do
[ -e "$file" ] || continue
mv "$file" "${file%$old}$new"
done
You can use rename to rename filenames.
rename .txt .text /home/name/*.txt
And if you want to do this by looping, you can
for FILE in /data/tmp/*.txt; do
mv "${FILE}" "${FILE/.txt/.text}"
done

Get current directory (not full path) with filename only when sub folder is present in Linux bash

I have prepared a bash script to get only the directory (not full path) with file name where file is present. It has to be done only when file is located in sub directory.
For example:
if input is src/email/${sub_dir}/Bank_Casefeed.email, output should be ${sub_dir}/Bank_Casefeed.email.
If input is src/layouts/Bank_Casefeed.layout, output should be Bank_Casefeed.layout. I can easily get this using basename command.
src/basefolder is always constant. In some cases (after src/email(basefolder) directory), sub_directories will be there.
This script will work. I can use this script (only if module is email) to get output. but script should work even if sub directory is present in other modules. Maybe should I count the directories? if there are more than two directories (src/basefolder), script should get sub directories. Is there any better way to handle both scenarios?
#!/bin/bash
filename=`basename src/email/${sub_dir}/Bank_Casefeed.email`
echo "filename is $filename"
fulldir=`dirname src/email/${sub_dir}/Bank_Casefeed.email`
dir=`basename $fulldir`
echo "subdirectory name: $dir"
echo "concatenate $filename $dir"
Entity=$dir/$filename
echo $Entity
Using shell parameter expansion:
sub_dir='test'
files=( "src/email/${sub_dir}/Bank_Casefeed.email" "src/email/Bank_Casefeed.email" )
for f in "${files[#]}"; do
if [[ $f == *"/$sub_dir/"* ]]; then
echo "${f/*\/$sub_dir\//$sub_dir\/}"
else
basename "$f"
fi
done
test/Bank_Casefeed.email
Bank_Casefeed.email
I know there might be an easier way to do this. But I believe you can just manipulate the input string. For example:
#!/bin/bash
sub_dir='test'
DIRNAME1="src/email/${sub_dir}/Bank_Casefeed.email"
DIRNAME2="src/email/Bank_Casefeed.email"
echo $DIRNAME1 | cut -f3- -d'/'
echo $DIRNAME2 | cut -f3- -d'/'
This will remove the first two directories.

Change Names of Multiple Files Linux

I have a number of files with names a1.txt, b1.txt, c1,txt...on ubuntu machine.
Is there any quick way to change all file names to a2.txt, b2.txt, c2.txt...?
In particular, I'd like to replace part of the name string. For instance, every file name contains a string called "apple" and I want to replace "apple" with "pear" in all file names.
Any command or script?
without any extra software you can:
for FILE in *1.txt; do mv "$FILE" $(echo "$FILE" | sed 's/1/2/'); done
for f in {a..c}1.txt; do echo "$f" "${f/1/2}"; done
replace 'echo' with 'mv' if the output looks correct.
and I want to replace "apple" with "linux"
for f in *apple*; do mv "$f" "${f/apple/linux}"; done
The curly brackets in line 1 should work with bash at least.
The following command will rename the specified files by replacing the first occurrence of 1 in their name by 2:
rename 1 2 *1.txt
ls *1.txt | perl -ne 'chomp; $x = $_; $x =~ s/1/2/; rename $_, $x;'
Here's another option that worked for me (following the examples above) for files in different subdirectories
for FILE in $(find . -name *1.txt); do mv "$FILE" "${FILE/1/2}"; done;
Something like this should work:
for i in *1.txt; do
name=$(echo $i | cut -b1)
mv $i ${name}2.txt
done
Modify to suit your needs.

Resources