Removing the file extension in a text file bash [duplicate] - linux

This question already has answers here:
Extract filename and extension in Bash
(38 answers)
Closed 6 years ago.
So I have put a load of names of files in a text file, these are specifically .log files:
ls *.log > finished_data.txt
Now that I Have the list of .log files, how do I keep the names but remove the .log extension?
My thought process is renaming them all?

Just loop through the .log files and move them:
for file in *.log
do
mv "$file" "${file%.log}"
done
This uses shell parameter expansion:
$ d="a.log.log"
$ echo "${d%.log}"
a.log

Using rename to rename all .log files by removing .log from the end:
rename 's/\.log$//' *.log
\.log$ matches .log at the end of the file name and it is being omitted by replacing with blank
If you are using prename, then you can do a dry-run first:
rename -n 's/\.log$//' *.log
If satisfied with the changes to be made:
rename 's/\.log$//' *.log

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

I need a script to replace old libraries with newer library in all files [duplicate]

This question already has answers here:
How to replace a string in multiple files in linux command line
(28 answers)
How can I use a file in a command and redirect output to the same file without truncating it?
(14 answers)
Looping through the content of a file in Bash
(16 answers)
How to loop over files in directory and change path and add suffix to filename
(6 answers)
Closed 3 years ago.
I have numerous files in a directory and want to replace one of the libraries used in all of these files with a newer library because the old library no longer works.
I have used ls > names.txt to list all filenames into a txt document. I then attempted to write a bash script which would loop through all files, catch the old library, and replace it with the new library.
for entry in names.txt
do
sed 's/<libOld>/<libNew>/g' $entry > $entry
done
I expect the loop to go through each file name, find the old library used, and replace it with the new one. Running this script however doesn't appear to do anything.
You're bumping into a few common issues; I've closed as a duplicate, but here are the collected fixes for your specific case:
Editing a file in-place with sed
With GNU sed:
sed -i 's/<libOld>/<libNew>/g' filename
with any sed:
sed 's/<libOld>/<libNew>/g' filename > filename.tmp && mv filename.tmp filename
Looping over a file line by line
for entry in names.txt only ever sets entry to names.txt, it doesn't read its contents. This is also BashFAQ/001.
while IFS= read -r entry; do
printf '%s\n' "$entry"
done < names.txt
Looping over all files in a directory
You don't need a separate file, and you shouldn't use ls but globs:
for fname in ./*; do
printf '%s\n' "$fname"
done
Combined for your case
Notice the double quotes around $entry.
for entry in ./*; do
sed -i 's/<libOld>/<libNew>/g' "$entry"
done
which can be simplified to no loop at all:
sed -i 's/<libOld>/<libNew>/g' ./*

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

sed changes are lost (while running cat command on txt file) [duplicate]

This question already has answers here:
Find and replace in file and overwrite file doesn't work, it empties the file
(12 answers)
sed edit file in place
(15 answers)
Closed 6 years ago.
I need to insert a command "new file" in a test.txt file at line number 4.
Tried sed; I can see the changed file output, but when I again do cat test.txt, the changes are gone.
sed "4i new file" /test.txt
How can I save the changes?
Use in place edit option sed -i "4i new file" test.txt
Without the -i option sed will not make any changes to the file. It will only print the result.
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if SUFFIX supplied)
sed '4i new file' test.txt > tmp && mv tmp test.txt

Resources