I have created this loop but I want to exclude some directories from the job. I tried different ways but it keeps working on all directories. Can you please help me?
for d in */
do
cd $d
echo $d
cartel=$(echo ${d} | sed 's/\///')
echo $cartel
I tried with:
shopt -s extglob
for d in this_folder/!(global|plugins|css)/
do
...
done
You can test explicitely for the directory you want to skip:
you can compare $d to the directories you want to avoid and go to the next loop using continue when you don't want to process this directory :
for d in */ ; do
if [ "$d" == "global/" ] || [ "$d" == "plugins/" ] || [ "$d" == "css/" ] ; then
continue
fi
cd $d
echo $d
cartel=$(echo ${d} | sed 's/\///')
echo $cartel
cd ..
done
Related
I want to find and print files in directory tree, that have the sname name as theirs dirs.
This is my code so far:
#!bin/bash
if [ $# -eq 0 ]
then
echo "No args"
fi
if [[ -d $1 ]] #if its dir
then
find $1 -type f | (while read var1 #for every regular file in dir tree
do
if [[ -f $var1 ]]
then
echo $var1 #full path
# I dont know how to get the dir name
echo $(basename $var1) #file name
echo
#then compare it and print full path
fi
done)
fi
I want to do this using FIND function in bash linux. Thanks
You can use this script with find:
while IFS= read -rd '' f; do
d="${f%/*}"
[[ ${d##*/} == ${f##*/} ]] && echo "$f"
done < <(find . -type f -print0)
I'm trying to write a shell script that will recursively count all the files and sub-directories in a directory and also all the hidden ones. My script can count them however it can't detect hidden files and directories that are in a sub-directory. How can i change it so that it is able to do this? Also i cannot use find, du or ls -R
#!/bin/bash
cd $1
dir=0
hiddendir=0
hiddenfiles=0
x=0
items=( $(ls -A) )
amount=( $(ls -1A | wc -l) )
counter() {
if [ -d "$i" ]; then
let dir+=1
if [[ "$i" == .* ]]; then
let hiddendir+=1
let dir-=1
fi
search "$i"
elif [ -f "$i" ]; then
let files+=1
if [[ "$i" == .* ]]; then
let files-=1
let hiddenfiles+=1
fi
fi
}
search() {
for i in $1/*; do
counter "$i"
done
}
while [ $x -lt $amount ]; do
i=${items[$x]}
counter "$i"
let x+=1
done
#!/bin/bash -e
shopt -s globstar dotglob # now ** lists all entries recursively
cd "$1"
dir=0 files=0 hiddendir=0 hiddenfiles=0
counter() {
if [ -f "$1" ]; then local typ=files
elif [ -d "$1" ]; then local typ=dir
else continue
fi
[[ "$(basename "$1")" == .* ]] && local hid=hidden || local hid=""
((++$hid$typ))
}
for i in **; do
counter "$i"
done
echo $dir $files $hiddendir $hiddenfiles
Consider using this:
find . | wc -l
I've the following script:
#!/bin/bash
ls -1 | while read d
do
[[ -f "$d" ]] && continue
echo $d
cd $d
done
Problem is that each cd says "[path]: No such file or directory", why?
Folder exists because I list it ...
I see two problems in your code:
You do not test for directories.
Once you cd in the dir, you stay there.
Please try this:
#!/bin/bash
ls -1 | while read d
do
test -d "$d" || continue
echo $d
(cd $d ; echo "In ${PWD}")
done
You shouldn't use ls like that.
#!/bin/bash
for d in */
do
[[ ! -d "$d" ]] && continue
echo "$d"
cd "$d"
# do something
cd "$OLDPWD"
done
Don't know what you are trying to achive.
Do you want to do some kind of recursive dic traversal ?
Here's ho I would do it:
#!/bin/bash
CWD="$(pwd)" #save starting directory
ls -1 | while read d
do
[[ ! -d "$d" ]] && continue
cd "$d"
echo "Changed to directory" $d
#Now you can do someting in the sub-directory
cd "$CWD" #Change back to old directory
done
The problem is you change the working directory in your script. This means that the second cd will be executed in the subdirectory you entered in the previous cd.
dir=`pwd`
ls -1 | while read d
do
[[ -f "$d" ]] && continue
cd "$dir"
echo $d
cd $d
#....
done
When I get an error like:
$ ls /var/django-projects/daks/public/media/uploads/bandsaws/sneaks.jpg
ls: /var/django-projects/daks/public/media/uploads/bandsaws/sneaks.jpg: No such file or directory
I'd like to be able to ask what-is-the-deepest-path-that-does-exists and get back, say:
/var/django-projects/daks/public/media/
I think it could be done with a loop that added ../ on each iteration and quitted when a path that exists was found.
You may well find dirname useful. Something such as:
f=/var/django-projects/daks/public/media/uploads/bandsaws/sneaks.jpg
until [ -e "$f" ]; do f=$(dirname "$f"); done
echo $f
should give you /var/django-projects/daks/public/media/
Try:
FILE="/var/django-projects/daks/public/media/uploads/bandsaws/sneaks.jpg"
while true; do [ -e "$FILE" ] && break || FILE=$(dirname "$FILE"); done; echo $FILE
#!/bin/bash
function firstValidParent () {
d="$1"
[ -e "${d}" ] && echo $d || firstValidParent "${d%/*}"
}
The directories are variables set to the full-path
for e in "$DIR_0" "$DIR_1" "$DIR_2"
do
for i in $e/*
do
echo $i
done
The output for each line is the full path. I want only the name of each file
You are looking for basename.
This is the Bash equivalent of basename:
echo "${i##*/}"
It strips off everything before and including the last slash.
If you truly do not wish to recurse you can achieve that more succinctly with this find command:
find "$DIR_0" "$DIR_1" "$DIR_2" -type f -maxdepth 1 -exec basename{} \;
If you wish to recurse over subdirs simply leave out maxdepth:
find "$DIR_0" "$DIR_1" "$DIR_2" -type f -exec basename{} \;
to traveling a directory recursively with bash
try this you can find it here
#! /bin/bash
indent_print()
{
for((i=0; i < $1; i++)); do
echo -ne "\t"
done
echo "$2"
}
walk_tree()
{
local oldifs bn lev pr pmat
if [[ $# -lt 3 ]]; then
if [[ $# -lt 2 ]]; then
pmat=".*"
else
pmat="$2"
fi
walk_tree "$1" "$pmat" 0
return
fi
lev=$3
[ -d "$1" ] || return
oldifs=$IFS
IFS=""
for el in $1/ *; do
bn=$(basename "$el")
if [[ -d "$el" ]]; then
indent_print $lev "$bn/"
pr=$( walk_tree "$el" "$2" $(( lev + 1)) )
echo "$pr"
else
if [[ "$bn" =~ $2 ]]; then
indent_print $lev "$bn"
fi
fi
done
IFS=$oldifs
}
walk_tree "$1" "\.sh$"
See also the POSIX compliant Bash functions to replace basename & dirname here:
http://cfaj.freeshell.org/src/scripts/