Check if there's some file on a directory regardless of another directory inside - linux ksh - linux

I'm trying to check if there's any file on a directory but i need it to be independent of the fact that can or cannot be another directory inside.
I'm using:
if [ -n "$(ls -A /unload/ebia 2>/dev/null)" ]
then
Exists="Yes"
else
Exists="No"
fi
echo "is any file inside $PATH ? $Exists."
If there's nothing on $PATH, it say no, and if there's any file inside, it say yes (it's correct), but if i create a directory inside $PATH, it keeps answering yes instead there's no file. How to avoid this?

use find:
if [ -n "$(find /unload/ebia/ -type f)" ]
then
Exists="Yes"
else
Exists="No"
fi
finds -type f switch only searches for files and skips directorys

Related

Displaying file content with bash scripting

I am trying to write a bash script (display) that will allow me to access a directory, list the files, and then display the content of all of the files. So far I am able to access the directory and list the files.
#!/bin/bash
#Check for folder name
if [ "$#" -ne 1 ]; then
echo " Usage: count [folder name]"
exit 1
fi
#Check if it is a directory
if [ ! -d "$1" ]; then
echo "Not a valid directory"
exit 2
fi
#Look at the directory
target=$1
echo "In Folder: $target"
for entry in `ls $target`; do
echo $entry
done
So if I use the command ./display [directory] it will list the files. I want to display the contents of all of the files as well but I am stuck. Any help would be appreciated thanks!
Use find to find files. Use less to display files interactively or cat otherwise.
find "$target" -type f -exec less {} \;
I thin a loop similar to your "look at the directory" loop would suffice, but using the cat command instead of ls

using IF to see a directory exists if not do something

I am trying to move the directories from $DIR1 to $DIR2 if $DIR2 does not have the same directory name
if [[ ! $(ls -d /$DIR2/* | grep test) ]] is what I currently have.
then
mv $DIR1/test* /$DIR2
fi
first it gives
ls: cannot access //data/lims/PROCESSING/*: No such file or directory
when $DIR2 is empty
however, it still works.
secondly
when i run the shell script twice.
it doesn't let me move the directories with the similar name.
for example
in $DIR1 i have test-1 test-2 test-3
when it runs for the first time all three directories moves to $DIR2
after that i do mkdir test-4 at $DIR1 and run the script again..
it does not let me move the test-4 because my loop thinks that test-4 is already there since I am grabbing all test
how can I go around and move test-4 ?
Firstly, you can check whether or not a directory exists using bash's built in 'True if directory exists' expression:
test="/some/path/maybe"
if [ -d "$test" ]; then
echo "$test is a directory"
fi
However, you want to test if something is not a directory. You've shown in your code that you already know how to negate the expression:
test="/some/path/maybe"
if [ ! -d "$test" ]; then
echo "$test is NOT a directory"
fi
You also seem to be using ls to get a list of files. Perhaps you want to loop over them and do something if the files are not a directory?
dir="/some/path/maybe"
for test in $(ls $dir);
do
if [ ! -d $test ]; then
echo "$test is NOT a directory."
fi
done
A good place to look for bash stuff like this is Machtelt Garrels' guide. His page on the various expressions you can use in if statements helped me a lot.
Moving directories from a source to a destination if they don't already exist in the destination:
For the sake of readability I'm going to refer to your DIR1 and DIR2 as src and dest. First, let's declare them:
src="/place/dir1/"
dest="/place/dir2/"
Note the trailing slashes. We'll append the names of folders to these paths so the trailing slashes make that simpler. You also seem to be limiting the directories you want to move by whether or not they have the word test in their name:
filter="test"
So, let's first loop through the directories in source that pass the filter; if they don't exist in dest let's move them there:
for dir in $(ls -d $src | grep $filter); do
if [ ! -d "$dest$dir" ]; then
mv "$src$dir" "$dest"
fi
done
I hope that solves your issue. But be warned, #gniourf_gniourf posted a link in the comments that should be heeded!
If you need to mv some directories to another according to some pattern, than you can use find:
find . -type d -name "test*" -exec mv -t /tmp/target {} +
Details:
-type d - will search only for directories
-name "" - set search pattern
-exec - do something with find results
-t, --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY
There are many examples of exec or xargs usage.
And if you do not want to overwrite files, than add -n option to mv command:
find . -type d -name "test*" -exec mv -n -t /tmp/target {} +
-n, --no-clobber do not overwrite an existing file

Find but do not descend into directories containing the searched files

I have several projects configured by a pom.xml or similar.
I would like to use the linux file command to locate these projects e.g. by find -name pom.xml.
This however takes some time because of the deep paths. I would like to use find -prune to stop searching in subdirectories when I already find the file, but prune only stops on matched directories not on matched files.
Is there a way to get find to stop descending when the directory aleady contains a searched file?
For clarification; this is what I do without find:
pfind() {
parent=$1 && shift
for file in "$#" ; do
path=$parent/$file
if [ -e "$path" ] ; then
echo "$path"
exit 0
fi
done
for dir in $(echo $parent/*) ; do
if [ -d "$dir" ] ; then
pfind "$dir" "$#"
fi
done
}
But I'd rather use a simple way with find so it is better understandable/extendable for others
find . -name pom.xml -print -quit
If you want to speed up the search, you can also work with locate, which queries a database instead of scanning the file system.
You can update the database using by running updatedb
One line python:
python -c 'import os; print "\n".join(p for p, d, f in os.walk(os.sys.argv[1], topdown=True) if os.sys.argv[2] in f and list(d.remove(i) for i in list(d)))' $PWD pom.xml
os.walk idea from https://stackoverflow.com/a/37267686/1888983

How to determine if a linux symbolic link points to a directory or a file

I have a directory that has symbolic links - some of them point to files and some of them to directories - how do I identify the ones poiting to directory in a shell script ( without any prejudice to names offcourse)
use ls -L option to follow symlinks
This is the script that I used to differentiate between directories with contents from files/empty directories
( this will work only if directory has some contents -- in my case I am anyway interested in those directories that have some content so I am happy - but do suggest better options if any
cd dir
for i in `ls `
do
if [ 1 -lt `ls -l -L $i | wc -l` ]
then
echo "$i is a non empty directory"
else
echo "$i is either an empty directory or a file"
fi
done

Recursively create directory tree within existing subdirectories

I have a working directory with a large number of subfolders (i.e 1190A, 1993A etc).
'/working/1190A'
'/working/1993A'
I would like to recursively create a certain directory tree within each subfolder. For example:
'/working/1190A/analysis/1'
'/working/1993A/analysis/1'
etc
Thanks.
To force the system create a directory tree without having to create each level of it, add -p to the mkdir command.
Hence, this could work:
for dir in list_of_folders
do
mkdir -p $dir/your/directory/tree
[ $? ] && echo "error on $dir" # if the dir could not be created, print error (thanks #hetepeperfan - see comments)
done
Note that the list_of_folders can be given like /working/1190A /working/1993A, but also generated with a find command. This is just a first version you'd better adapt to your specific requirements.
This is one liner as
cd /working
find . -maxdepth 1 -type d -exec mkdir -p '{}'/analysis/1 \;
yourDirList=/working/*
for f in $yourDirList
do
if [ -d $f ]
mkdir -p $f/analysis/1
fi
done

Resources