Not getting desired out put while using 'OR' operation in Bash Scripting - bash

My OS : Fedora release 13 (Goddard)
There is 5 directories under 'test'
[root#localhost lab]# ls test
dir1 dir2 dir3 dir4 dir5
Script1
#!/bin/bash
#below line for listing all directories under '/home/arun/lab/test'
ls -Al --time-style=long-iso /home/arun/lab/test | grep '^d' | awk '{print $8}' | while read line
do
#Need to skip few directoirs
if [ "$line" == "dir1" -o "$line" == "dir2" ]; then
continue
fi
#will take some actions here..as of now just echo only
echo $line
done
Script2[Only Modification is changed == to != ]
#!/bin/bash
#below line for listing all directories under '/home/arun/lab/test'
ls -Al --time-style=long-iso /home/arun/lab/test | grep '^d' | awk '{print $8}' | while read line
do
#Need to skip few directoirs
if [ "$line" != "dir1" -o "$line" != "dir2" ]; then
continue
fi
#will take some actions here..as of now just echo only
echo $line
done
Script 1 giving expected o/p
[root#localhost lab]# ./test.sh
dir3
dir4
dir5
Issue is :
For script 2 , I am expecting below o/p. But there is no o/p [blank] while running .. Please help me in this.
[root#localhost lab]# ./test.sh
dir1
dir2

For the second script, you want -a ("and") instead of -o ("or"). Think the logic through: every possible string is not equal to at least one of the two, but you want to skip when it's not equal to either of them, which is to say when it's not equal to "dir1" and it's also not equal to "dir2".

Related

How to find symlinks in a directory that points to another

I need to write a bash script that finds and lists symlinks from one directory (lets say some "Directory1") but only the ones pointing to files in certain another directory (lets say "Directory2"). I can`t use "find".
I have tried something like this but it's apparently wrong:
if [[ -d $1 ]]&&[[ -d $2 ]]
then
current_dir='pwd'
cd $1
do
for plik in *
if[[-L $file] && ["$(readlink -- "$file")" = "$2"] ]
then
#ls -la | grep ^l
echo "$(basename "$file")"
fi
done
fi
How about a simple ls with grep :
ls -l Directory1/ | grep "\->" | grep "Directory2"
I have found a solution:
for file1 in $_cat1/* do
if [ -L $file1]; then
dir1="$(dirname `readlink -f $file1`)"
dir2="$(dirname `readlink -f $_cat2`)"
if [dir1 == dir2]
echo $dir1
fi
fi
done

Determine the maximum path length of a directory in bash

I'm trying to create an hierarchy of directories and files. The idea is the following : i want my script to create my directories level by level
So lets say the user types these commands from command line
/dirname #dirs=8 #levels=2
and i want it to create something like this:
/dirname
|-->/a/b
|
|-->/b/c
|
|-->/e/f
|
|-->/g/h
How can i determine the number of paths i will have in my directories
i've tried with PATH_MAX but it doesnt seem to work
#!/bin/bash
ARG_NUM=$# #argc
echo $#
if [ $ARG_NUM -ne 3 ];then
echo "Wrong number of aguments"
exit 1
fi
# ROOT_DIR
dir_name=$1
if [[ ! -d $dir_name ]]; then
mkdir $dir_name
fi
#CREATING FOLDERS WITH RANDOM NAMES
LIMIT=$3
for ((j=1; j<=LIMIT; j++))
do
mkdir -p $dir_name/$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
echo $dir_name "created"
done

Need to remove the extra empty lines from the output of shell script

i'm trying to write a code which will print all files taking more than min_size (lets say 10G) in a directory. the problem is output off the below code is all files irrespective of the min_size. i will be getting other details like mtime , owner as well later in the code but this part itself doesnt work fine, whats wrong here ?
#!/bin/sh
if (( $# <3 )); then
echo "$0 dirname min_size count"
exit 1
else
dirname="$1";
min_size="$2";
count="$3";
#shift 3
fi
tmpfile=$(mktemp /lawdump/pulkit/files.XXXXXX)
exec 3> "$tmpfile"
find "${dirname}" -type f -print0 2>&1 | grep -v "Permission denied" | xargs -0 -I {} echo "{}" > "$tmpfile"
for i in `cat tmpfile`
do
x="`du -ah $i | awk '{print $1}' | grep G | sort -nr -k 1`"
size=$(echo $x | sed 's/[A-Za-z]*//g')
if [ size > $min_size ];then
echo $size
fi
done
Note : i know this can be done through find or du but i need to write a shell script to have an email sent out regularly with all the details.

Shell script: check if any files in one directory are newer than any files in another directory

I want to run a command in a shell script if files in one directory have changed more recently than files in another directory.
I would like something like this
if [ dir1/* <have been modified more recently than> dir2/* ]; then
echo 'We need to do some stuff!'
fi
As described in BashFAQ #3, broken down here into reusable functions:
newestFile() {
local latest file
for file; do
[[ $file && $file -nt $latest ]] || latest=$file
done
}
directoryHasNewerFilesThan() {
[[ "$(newestFile "$1"/*)" -nt "$(newestFile "$2" "$2"/*)" ]]
}
if directoryHasNewerFilesThan dir1 dir2; then
echo "We need to do something!"
else
echo "All is well"
fi
If you want to count the directories themselves as files, you can do that too; just replace "$(newestFile "$1"/*)" with "$(newestFile "$1" "$1"/*)", and likewise for the call to newestFile for $2.
Using /bin/ls
#!/usr/bin/ksh
dir1=$1
dir2=$2
#get modified time of directories
integer dir1latest=$(ls -ltd --time-style=+"%s" ${dir1} | head -n 2 | tail -n 1 | awk '{print $6}')
integer dir2latest=$(ls -ltd --time-style=+"%s" ${dir2} | head -n 2 | tail -n 1 | awk '{print $6}')
#get modified time of the latest file in the directories
integer dir1latestfile=$(ls -lt --time-style=+"%s" ${dir1} | head -n 2 | tail -n 1 | awk '{print $6}')
integer dir2latestfile=$(ls -lt --time-style=+"%s" ${dir2} | head -n 2 | tail -n 1 | awk '{print $6}')
#sort the times numerically and get the highest time
val=$(/bin/echo -e "${dir1latest}\n${dir2latest}\n${dir1latestfile}\n${dir2latestfile}" | sort -n | tail -n 1)
#check to which file the highest time belongs to
case $val in
#(${dir1latest}|${dir1latestfile})) echo $dir1 is latest ;;
#(${dir2latest}|${dir2latestfile})) echo $dir2 is latest ;;
esac
It's simple, get times stamps of both the folders in machine format(epoch time) then do simple comparison. that's all

Is there any command to step down one directory in shell?(when there is only one sub-directory)

To go up one directory I write cd ..
Is there any command that would work for the reverse situation in which there is only one subdirectory?
Let's say I am in:
dir1/dir2/
dir2 has only one subdirectory dir3
Is there any short cut to step down one directory from dir2 to dir3 without writing the name of subdirectory(dir3)?
There isn't such command per se, but you can trick the cd command by typing cd */ ;-)
At the time of my question I was not aware of shells's auto-complete with Tab key.
In this scenario I just type cd, press Tab and the name of the directory shows up so I can press Enter to move to the directory.
I had a similar thought when I was learning shell and wrote a wrapper around cd that does what you want. It grew into something a bit more complicated. If you have folders called folder1 and folder2 you can type: cdd 2
If there is only one folder you can just type: cdd
It also has a similar functionality to ksh's cd paths substitution with 2 args (if at /home/tom, you can type the following to get to /home/bob: cdd tom bob).
It also works like the normal cd command if you pass a folder that exists.
It was written a while ago so it might not be the prettiest, but it works.
It also does an ls at the end which you can remove.
One other thing to note is you can (in bash at least) type the following to go the the previous directory you were in: cd -
function cdd()
{
if [[ $3 != "" ]]; then
printf "~~~ cdd can only take 1 or 2 arguments, you specified 3 or more\n";
return;
else
if [[ $2 != "" ]]; then
ARG=$(pwd | sed "s/$1/$2/g");
cd $ARG;
else
if [[ $1 == "" ]]; then
cd $(ls -d */ | head -1);
else
if [[ -d $1 ]]; then
cd $1;
else
if [[ -d $(ls -F | grep "/$" | grep "^$1" | head -1) ]]; then
cd $(ls -F | grep "/$" | grep "^$1" | head -1);
else
if [[ -d $(ls -F | grep "/$" | grep "$1/$" | head -1) ]]; then
cd $(ls -F | grep "/$" | grep "$1/$" | head -1);
else
if [[ -d $(ls -F | grep "/$" | grep "$1" | head -1) ]]; then
cd $(ls -F | grep "/$" | grep "$1" | head -1);
else
if [[ -d $(ls -a -F | grep "/$" | grep "$1" | head -1) ]]; then
cd $(ls -a -F | grep "/$" | grep "$1" | head -1);
else
printf "~~~ Folder not found...\n";
return 3;
fi;
fi;
fi;
fi;
fi;
fi;
fi;
fi;
if [[ $? == 0 ]]; then
ls --color=auto -a --color;
fi
}

Resources