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

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

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

Rename a file to swap extensions in Unix

I have a bunch of files which are copied by "mv --backup=t source destination". So these files are in format *.*.~[0-9]~
For example,
some_file_name.pdf.~1~
some_file_name.pdf.~2~
another_file_name.docx.~1~
another_file_name.docx.~2~
Now, I would like to rename all such files so that the backup extension number came before the actual extension. Like
some_file_name_1.pdf
some_file_name_2.pdf
another_file_name_1.docx
another_file_name_2.docx
Is there a way to do in Unix using shell?
Any thoughts would be appreciated. Thank you in advance.
Using BASH regex directives you can do this:
for f in *~; do
[[ $f =~ ^(.+)\.([^.]+)\.~([0-9]+)~$ ]] &&
echo mv "$f" "${BASH_REMATCH[1]}_${BASH_REMATCH[3]}.${BASH_REMATCH[2]}"
done
Output:
mv CR_71050_5.3.17.pdf.~1~ CR_71050_5.3.17_1.pdf
mv another_file_name.docx.~1~ another_file_name_1.docx
mv another_file_name.docx.~2~ another_file_name_2.docx
mv some_file_name.pdf.~1~ some_file_name_1.pdf
mv some_file_name.pdf.~2~ some_file_name_2.pdf
Once you're satisfied, you can remove echo before mv
Try:
awk -F~ '{ split($1,splt,".");system("mv "$0" "splt[1]"_"$2"."splt[2]) }'
We are essentially splitting the filenames on ~ and then using awks split function to further split the text and then pass it to the system function to execute the mv command.
You can use rename (it is available as a Debian package).
$ ls
file.pdf.~1~ file.pdf.~10~ file.pdf.~2~ file.pdf.~3~ file.pdf.~9~
$ rename 's/.pdf.~([0-9]+)~$/$1.pdf/' *.pdf.~*~
$ ls
file10.pdf file1.pdf file2.pdf file3.pdf file9.pdf

Rename Two files in the Same Folder

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 .

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

Rename all files in directory from $filename_h to $filename_half?

Dead simple.
How do I rename
05_h.png
06_h.png
to
05_half.png
06_half.png
At least, I think it's simple, but it's hard to Google for this kind of thing unless you already know.
Thanks....
Just use bash, no need to call external commands.
for file in *_h.png
do
mv "$file" "${file/_h.png/_half.png}"
done
Do not add #!/bin/sh
For those that need that one-liner:
for file in *.png; do mv "$file" "${file/_h.png/_half.png}"; done
Try rename command:
rename 's/_h.png/_half.png/' *.png
Update:
example usage:
create some content
$ mkdir /tmp/foo
$ cd /tmp/foo
$ touch one_h.png two_h.png three_h.png
$ ls
one_h.png three_h.png two_h.png
test solution:
$ rename 's/_h.png/_half.png/' *.png
$ ls
one_half.png three_half.png two_half.png
for f in *.png; do
fnew=`echo $f | sed 's/_h.png/_half.png/'`
mv $f $fnew
done
Or in one-liner:
for f in *.png; do mv "$f" "$(echo $f | sed 's/_h.png$/_half.png/g')"; done
Are you looking for a pure bash solution? There are many approaches, but here's one.
for file in *_h.png ; do mv "$file" "${file%%_h.png}_half.png" ; done
This presumes that the only files in the current directory that end in _h.png are the ones you want to rename.
Much more specifically
for file in 0{5..6}_h.png ; do mv "$file" "${file/_h./_half.}" ; done
Presuming those two examples are your only. files.
For the general case, file renaming in has
been covered
before.
Use the rename utility written in perl.
Might be that it is not available by default though...
$ touch 0{5..6}_h.png
$ ls
05_h.png 06_h.png
$ rename 's/h/half/' *.png
$ ls
05_half.png 06_half.png
for i in *_h.png ; do
mv $i `echo "$i"|awk -F'.' '{print $1"alf."$2}'`
done
I had a similar question:
In the manual, it describes rename as
rename [option] expression replacement file
so you can use it in this way
rename _h _half *.png
In the code:
'_h' is the expression that you are looking for.
'_half' is the pattern that you want to replace with.
'*.png' is the range of files that you are looking for your possible target files.
Hope this can help c:
Another approach can be manually using batch rename option
Right click on the file -> File Custom Commands -> Batch Rename
and you can replace h. with half.
This will work for linux based gui using WinSCP etc
One liner:
for file in *.php ; do mv "$file" "_$file" ; done
Although the answer set is complete, I need to add another missing one.
for i in *_h.png;
do name=`echo "$i" | cut -d'_' -f1`
echo "Executing of name $name"
mv "$i" "${name}_half.png"
done
I had to rename the prefix of files and I found this answer with a solution like this:
for i in h_*; do mv ${i/#h_/half_}; done
If pattern begins with #, it must match at the beginning of the
expanded value of parameter. If pattern begins with %, it must match
at the end of the expanded value of parameter.
from man bash
Use the rename utility:
rc#bvm3:/tmp/foo $ touch 05_h.png 06_h.png
rc#bvm3:/tmp/foo $ rename 's/_h/_half/' *
rc#bvm3:/tmp/foo $ ls -l
total 0
-rw-r--r-- 1 rc rc 0 2011-09-17 00:15 05_half.png
-rw-r--r-- 1 rc rc 0 2011-09-17 00:15 06_half.png

Resources