Rename Two files in the Same Folder - bash

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 .

Related

How to read each file in a folder using cat (recursively) and store it in a file?

I have a file with 9k PDF documents. I wish to read the source code (not content) of each of them using cat and store them in a separate text file with the same name as that of the PDF.
For example
cat 030.pdf > 030.txt
I want to do this for all the files in the folder. How can I do it?
Instead of using cat use cp it's more efficient.
find . -name \*.pdf -exec cp {} $(basename {}).txt \;
You could use create a shell script to loop through files in the directory and execute the cat command, and substring the filename to remove .pdf and add .txt:
for entry in "$search_dir"/*
do
if [ -f "$entry" ];then
cat "$entry" > "${entry%%.*}.txt"
fi
done

Renaming only csv files in a directory using Shell

I'm replacing some contents in the files that have extension .csv in a directory . Is there a way to rename multiple files differently and using sed command.
For example The directory has two file with the following name
data_20050523-20170409.csv
data_20050523-20170409FileHeader.csv
I want to use sed and rename both files as different name for example
new_data.csv or data1.csv
new_data_header.csv or data2.csv
Is it possible to do so in Shell Script ?
DIR=/Users/test/Desktop/NPPES/
cd $DIR
sed 's/","/|/g;s/"/''/g' *.csv
echo Replace completed
#cd $DIR
#rm $FILE
#rm *.pdf
#chmod 777 *.csv
#echo file removed
echo Script completed
Thank you in advance
# Iterate over all csv files in folder
for csv in *.csv; do
# Generate new name with sed
new=`echo "$csv" | sed 's/something/something_else/'`
# Rename csv if new name different
[ "$new" = "$csv" ] || mv "$csv" "$new"
done
But there is also a rename utility, which can do this in one go, using a Perl expression:
rename 's/something/something_else/' *.csv
The problem is that there are 2 rename tools that work completely differently, the one from the util-linux Deb package is not the Perl based one.

Bash - how do I wipe the contents of all files in a directory

is it possible to wipe the contents of all given files in a directory? e.g. if I have a bunch of .csv files I want wiped.
I generally use "# > .csv" on the command line for a single csv file, but a "# > *.csv" results in a error: bash: *.csv: ambiguous redirect
I have tried piping /dev/null to *.csv but get same result. When I have a directory full of files whose content I want wiped, it's a real pain.
If I use a script and for loop on all the files I get the same error when using the redirect on the $f (the file) in the loop.
Thanks
for f in *.csv; do
> "$f"
done
You can use truncate for the same :
truncate -s 0 *.csv
When you say "wipe" you mean:
"overwite" with random content,
or an simple "truncate"
or even simpler delete?
Delete:
rm *.csv #will delete all .csv file in the currect directory
Truncate
see #John Zwinkcs answer
Overwrite with random and delete
shopt -s nullglob
for file in *.csv
do
echo "wiping $file" >&2
eval "$(gstat -c 'count=%b;blocksize=%B' "$file")"
dd if=/dev/random of="$file" bs="$blocksize" count="$count" 2>/dev/null
rm "$file"
done
This is a way using sed
sed -i '1,$d' *.csv
also
sed -ni '' *.csv

In Unix using shell to rename multiple files

There are many files and names like *.txt; how can I rename all the files to *YYYYMMDD.txt
with a shell script.
Since this is a move operation and could be quite dangerous if done wrong:
Run this first to make sure the script generates correct command
ls *.txt | while read FILE; do echo mv "$FILE" "${FILE/.txt/`date +%Y%m%d.txt`}"; done
Then when you are sure
ls *.txt | while read FILE; do mv "$FILE" "${FILE/.txt/`date +%Y%m%d.txt`}"; done

How can I manipulate file names using bash and sed?

I am trying to loop through all the files in a directory.
I want to do some stuff on each file (convert it to xml, not included in example), then write the file to a new directory structure.
for file in `find /home/devel/stuff/static/ -iname "*.pdf"`;
do
echo $file;
sed -e 's/static/changethis/' $file > newfile +".xml";
echo $newfile;
done
I want the results to be:
$file => /home/devel/stuff/static/2002/hello.txt
$newfile => /home/devel/stuff/changethis/2002/hello.txt.xml
How do I have to change my sed line?
If you need to rename multiple files, I would suggest to use rename command:
# remove "-n" after you verify it is what you need
rename -n 's/hello/hi/g' $(find /home/devel/stuff/static/ -type f)
or, if you don't have rename try this:
find /home/devel/stuff/static/ -type f | while read FILE
do
# modify line below to do what you need, then remove leading "echo"
echo mv $FILE $(echo $FILE | sed 's/hello/hi/g')
done
Are you trying to change the filename? Then
for file in /home/devel/stuff/static/*/*.txt
do
echo "Moving $file"
mv "$file" "${file/static/changethis}.xml"
done
Please make sure /home/devel/stuff/static/*/*.txt is what you want before using the script.
First, you have to create the name of the new file based on the name of the initial file. The obvious solution is:
newfile=${file/static/changethis}.xml
Second you have to make sure that the new directory exists or create it if not:
mkdir -p $(dirname $newfile)
Then you can do something with your file:
doSomething < $file > $newfile
I wouldn't do the for loop because of the possibility of overloading your command line. Command lines have a limited length, and if you overload it, it'll simply drop off the excess without giving you any warning. It might work if your find returns 100 file. It might work if it returns 1000 files, but it might fail if your find returns 1000 files and you'll never know.
The best way to handle this is to pipe the find into a while read statement as glenn jackman.
The sed command only works on STDIN and on files, but not on file names, so if you want to munge your file name, you'll have to do something like this:
$newname="$(echo $oldname | sed 's/old/new/')"
to get the new name of the file. The $() construct executes the command and puts the results of the command on STDOUT.
So, your script will look something like this:
find /home/devel/stuff/static/ -name "*.pdf" | while read $file
do
echo $file;
newfile="$(echo $file | sed -e 's/static/changethis/')"
newfile="$newfile.xml"
echo $newfile;
done
Now, since you're renaming the file directory, you'll have to make sure the directory exists before you do your move or copy:
find /home/devel/stuff/static/ -name "*.pdf" | while read $file
do
echo $file;
newfile="$(echo $file | sed -e 's/static/changethis/')"
newfile="$newfile.xml"
echo $newfile;
#Check for directory and create it if it doesn't exist
$dirname=$(dirname "$newfile")
if [ ! -d "$dirname" ]
then
mkdir -p "$dirname"
fi
#Directory now exists, so you can do the move
mv "$file" "$newfile"
done
Note the quotation marks to handle the case there's a space in the file name.
By the way, instead of doing this:
if [ ! -d "$dirname" ]
then
mkdir -p "$dirname"
fi
You can do this:
[ -d "$dirname"] || mkdir -p "$dirname"
The || means to execute the following command only if the test isn't true. Thus, if [ -d "$dirname" ] is a false statement (the directory doesn't exist), you run mkdir.
It's a fairly common shortcut when you see shell scripts.
find ... | while read file; do
newfile=$(basename "$file").xml;
do something to "$file" > "$somedir/$newfile"
done
OUTPUT="$(pwd)";
for file in `find . -iname "*.pdf"`;
do
echo $file;
cp $file $file.xml
echo "file created in directory = {$OUTPUT}"
done
This will create a new file with name whatyourfilename.xml, for hello.pdf the new file created would be hello.pdf.xml, basically it creates a new file with .xml appended at the end.
Remember the above script finds files in the directory /home/devel/stuff/static/ whose file names match the matcher string of the find command (in this case *.pdf), and copies it to your present working directory.
The find command in this particular script only finds files with filenames ending with .pdf If you wanted to run this script for files with file names ending with .txt, then you need to change the find command to this find /home/devel/stuff/static/ -iname "*.txt",
Once I wanted to remove trailing -min from my files. i.e. wanted alg-min.jpg to turn into alg.jpg. so after some struggle, managed to figure something like this:
for f in *; do echo $f; mv $f $(echo $f | sed 's/-min//g');done;
Hope this helps someone willing to REMOVE or SUBTITUDE some part of their file names.

Resources