For i in loop on file uses filename as well - bash

So here is my problem when using code:
for i in filename.txt
do
<operations>
done
Operations are being made on both file contents as well as filename itself, why is that happening?
Just to be clear I alread got 2 solutions that solve this problem, but I still can't understand why is that happening.
One of the solutions that have worked for me:
for i in $(cat filename.txt)
do
tar -czf ${i}.tar $i
rm -R $i
gzip $i.tar
done

"Yes. In for i in filename.txt you will have one $i and it will be set to filename.txt. If you want to read the contents of $i - do that in the loop."
Thank you Ted Lyngmo.

Related

Bash script to run chmod and skip wile with badstr

I apologize for my question but I am a beginner and I am starting to code and learn and I have no clue what am I doing but still I am learning. I took community course and struggled with my homework. 2 of the 3 assignments I've done and I'm struggling with no 3.
Assignment is:
"write BASH script to run CHMOD 644 command on file /folder/file1, /folder/file2 up to file /folder/file28 and skip all files containing string badstr. I have no clue how to do it, I am searching and reading all morning and still didn't figure it out. Can someone please help me?
Go step by step:
Create a loop over the files (which means that you have to generate that list of files) -> for
Check if every file being processed contains the forbidden string -> grep
Perform the chmod if the file passes the test -> if, test, chmod
So based on your answer i got this now. Hopefully i am on right track
#!/bin/bash
FILES=/path/to/*
for f in $FILES
do
echo "Processing $f file..."
cat $f
while read -r str
do
echo "$str"
grep "$str" /path/to/other/files
done < inputfile
chmod g+w `cat inputfile

Looping though all .sh files in a directory to find specific text in each one

I have a bunch of .sh files in a directory. I need to find out how many stored procedures each one of them calls. What would be the best way to do that?
I'm REALLY new with bash scripts so this is all very new to me. From what I looked online I hacked up a starting point (I think) but I have no idea how I would open each file, and find "something.sql" in it and then out put number of times that was found in each file.
Here's what I have:
#!/bin/sh
for i in 'ls *.sh'
echo -e "\n **** START****"
do
echo -e " \n Filename: $i"
done
echo -e "\n **** END ****"
done
Thanks for any help!
Try this:
grep -nc sql *.sh
See how that moves you. You can add -i if you name sql files in as file.SQL too. Or if they all have a .sql extension.
grep -nc '\.sql' *.sh
For you comment you added, try this:
for i in *.sh
grep -Hc '\.sql' $i
grep '\.sql' $i
done

delete files in a sequence and count in shell

In a specific Unix directory on a server. I would like to list down files and delete them in a sequence one by one.
Below program is showing errors in for loop. Can anybody help to make it work?
#!/bin/sh
address=/apps/applications/jboss-as/servers/scripts/
files=$(ls $address)
echo Below files will be deleted-
echo $files
k=0
for i in "$files" do {
rm $i
k++
}
done
echo ${k} files are deleted.
I fixed the script, but as others pointed out, you may want to use something other than the ls, but I left it in. There were other syntax errors as well. Here it is:
#!/bin/bash
address=/apps/applications/jboss-as/servers/scripts/
files=("$address"/*)
echo Below files will be deleted-
echo "${files[#]}"
k=0
for i in "${files[#]}" ; do
echo "removing $i ..."
rm "$i"
((k++))
done
echo ${k} files are deleted.
UPDATE:
Since you're still having trouble, you might add declare -a files just above the files=( "$address"/* ). It might fix the problem for you (but, the script runs fine without it here), and it doesn't hurt anything when I run the script here with it. So, either way ...
The first question is, what kind of error do you got?
Try this:
for file in $(ls ${files}/*); do
...
done
Best regards
Robert

read all files in directory ksh

I want to read all files one by one from the /home/ram/files/*.txt
and I want to remove the file If the file has less than or equal to 7 lines.
I am using ksh script
The follwoing code not working for me! pls help
for file in /home/ram/files/*.txt
do
no_of_lines=$(wc -l "$file")
if [[ $no_of_lines -le 7 ]];
then
rm "$file"
fi
done
Thanks,
Ram
wc command gives count and the filename as well.
Change it to:
no_of_lines=$(wc -l < "$file")

Script to rename files using a sha1() hash of their filename

I'm building a website and I would like to hash the filenames of my images.
How can I create a bash script file that renames every file in a directory with the sha1 of the old filename ?
I've tried :
#!/bin/bash
for file in *
do
if [ -f "$file" ];then
newfile="openssl sha1 $file"
mv "$file" $newfile"
fi
done
But that doesn't work :(
EDIT
Based on suggestions here I tried this :
#!/bin/bash
for file in old_names/*
do
if [ -f "$file" ];then
newfile=$(openssl sha1 $file | awk '{print $2}')
cp $file new_names/$newfile.png
fi
done
This does rename the files, but I'm not sure what has been used to hash the file name. Did the extention get hashed ? did the path ?
INFO
I will then use PHP's sha1() function to display the images :
echo "<img src=\"images/".sha1("$nbra-$nbrb-".SECRET_KEY).".png\" />\n";
The code examples in the answers so far and in your edit hash the contents of the file. If you want to create filenames that are hashes of the previous filename, not including the path or extension, then do this:
#!/bin/bash
for file in old_names/*
do
if [ -f "$file" ]
then
base=${file##*/}
noext=${base%.*}
newfile=$(printf '%s' "$noext" | openssl sha1)
cp "$file" "new_names/$newfile.png"
fi
done
Try this:
newfile=$(openssl sha1 $file | awk '{print $2}')
mv $file $newfile
I was trying to do the same sorta thing but the snippets here weren't /exactly/ what I needed, plus I'm brand new to bash scripting... sorry... In the end I stuck several ideas together into the script that does what I need which is -- look at the files in ./pics and rename them to their old hash while maintaining the current extension. I've tested this on a bunch of different pictures and so far it works as intended. I imagine another newbie such as myself would be able to copy/paste this in and be good to go if your end result happens to be the same as mine. Thanks everyone for the help!
#!/bin/bash
for file in ./pics/*
do
newfile=$(openssl sha1 $file | awk '{print $2}')
ext=${file##*.}
mv "$file" "./pics/$newfile"."$ext"
done
try
newfile=$(openssl sha1 $file)
mv "$file" "${newfile##*= }"

Resources