shell list All Xcode xcworkspace and xcodeproj - xcode

I want to list project directory all xcworkspace and xcodeproj file.
And I write code below
#!/bin/bash
workspaceFile="xcworkspace"
projectFile="xcodeproj"
#listFiles
path=$(pwd)
fileList=()
walk_dir () {
for name in "$path"/*; do
if [[ -d "$name" && ("${name##*.}" != ${projectFile} || "${name##*.}" != ${workspaceFile}) ]]; then
path=$name
walk_dir "$name"
else
if [ "${name##*.}"x = ${workspaceFile}x ] || [ "${name##*.}"x = ${projectFile}x ];then
fileList+=($name)
fi
fi
done
}
walk_dir
for name in ${fileList[#]}; do
echo $name
done
It did not work.
But If change the condition, like below
if [[ -d "$name" && ("${name##*.}" != ${workspaceFile}) ]]; then
path=$name
walk_dir "$name"
else
if [ "${name##*.}"x = ${workspaceFile}x ] || [ "${name##*.}"x = ${projectFile}x ];then
fileList+=($name)
fi
fi
or
if [[ -d "$name" && ("${name##*.}" != ${projectFile}) ]]; then
path=$name
walk_dir "$name"
else
if [ "${name##*.}"x = ${workspaceFile}x ] || [ "${name##*.}"x = ${projectFile}x ];then
fileList+=($name)
fi
fi
It works also.
I want to keep filter xcworkspace and xcodeproj.
Someone can help me?

Finaly, I found result by myself.
#!/bin/bash
workspaceFile="xcworkspace"
projectFile="xcodeproj"
path=$1
fileList=()
projectList () {
for name in "$path"/*; do
if [ -d "$name" ] && [ "${name##*.}"x = ${workspaceFile}x ]; then
fileList+=(${name})
elif [ -d "$name" ] && [ "${name##*.}"x = ${projectFile}x ]; then
fileList+=(${name})
elif [ -d "$name" ]; then
path=$name
projectList
fi
done
}
projectList
for name in ${fileList[#]}; do
echo "xcode project: $name"
done

Related

How to use elif with && and -o in a bash script properly

Bash version 4.4.20
Ubuntu 16.04
I need to compare time and extensions for a particular project I have. Below is something similar to what I am trying to do but the error is the same. I am not sure where exactly the error is as shellcheck is not producing one.
#!/bin/bash
#
while read -r filename; do
extension="${filename##*.}"
if [ "$extension" == "zip" ] && [ "$filename" == "one.zip" ]; then
echo "Filename is $filename"
elif [ "$extension" == "zip" ] && [ "$filename" == "file_1.zip" ] -o [ "$filename" == "file_2.zip" ] -o [ "$filename" == "file_3.zip" ]; then
echo "Filename is $filename"
elif [ "$extension" == "csv" ] && [ "$filename" == "two.csv" ]; then
echo "Filename is $filename"
else
echo "Filename is $filename"
fi
done<fileList.txt
Error:
Filename is one.zip
check.sh: line 8: [: too many arguments
Filename is file_1.zip
check.sh: line 8: [: too many arguments
Filename is file_2.zip
check.sh: line 8: [: too many arguments
Filename is file_3.zip
Filename is two.csv
Filename is three.sql
Use pattern matching to your advantage:
while IFS= read -r filename; do
if [[ "$filename" = one.zip ]; then
echo "Filename is $filename"
elif [[ "$filename" = file_[123].zip ]; then
echo "Filename is $filename"
elif [[ "$filename" = two.csv ]; then
echo "Filename is $filename"
else
echo "Filename is $filename"
fi
done < fileList.txt
A case statement will work in any POSIX shell, not just a shell that supports a bash-like [[ ... ]] command.
while IFS= read -r filename; do
case $filename in
one.zip) echo "Filename is $filename" ;;
file_[123].zip) echo "..." ;;
two.csv) echo "..." ;;
*) echo "..." ;;
esac
done
To match a range of years(?), you can use
case $value in
200[0-9]|201[0-9]|202[0-1]) echo "Year between 2000 and 2021" ;;
esac
You can't do that as simply with [[ value = ... ]], since the | is part of the case statement's syntax, not an alternation operator in the pattern. Instead, you would need multiple match operators:
if [[ $value = 200[0-9] || $value = 201[0-19] || $value = 202[0-1] ]]; then
Here an explanation for why you get this error, as you get already good answers on how to do it correctly:
Note that the command [ is equivalent to test, hence your line 8 in effect (also removing unnecessary quotes) contains:
elif test "$extension" == zip ] && test "$filename" == file_1.zip ] -o [ "$filename" == file_2.zip ] -o [ "$filename" == file_3.zip ]
From the test man-page, we can see that the closing ] is optional, but if it is present, it terminates the expression to be tested.
The first test, which is just
test "$extension" == "zip" ]
is fine in this respect, but the second one starts with
test "$filename" == file_1.zip ] -o [ ...
Hence, when parsing the arguments, test encounters a ] and knows that this is the terminator for the arguments, but then finds another argument (-o), and doesn't know what to do with it. Hence it complains that it has got too many arguments
I have updated the syntax to what I think is the modern bash idioms. The script now works. Please correct me if I missed something else :
#!/bin/bash
#
while read -r filename
do
extension="${filename##*.}"
if [[ "$extension" = "zip" && "$filename" = "one.zip" ]]
then
echo "Filename is $filename"
elif [[ "$extension" = "zip" && "$filename" = "file_1.zip" ]] \
|| [[ "$filename" = "file_2.zip" ]] \
|| [[ "$filename" = "file_3.zip" ]]
then
echo "Filename is $filename"
elif [[ "$extension" = "csv" && "$filename" = "two.csv" ]]
then
echo "Filename is $filename"
else
echo "Filename is $filename"
fi
done < fileList.txt
Regards!

Parameter from URL into shell script

How is it possible to get an URL parameter like /?photo=1.png into a shell script as a variable, running into a cgi-bin container on apache?
Edit
Iam generating a list of all files in a directory.
#!/bin/bash
echo "Content-type: text/html"
echo
for file in /var/www/html/export/tui/*;
do
echo "<a href='/cgi-bin/test.cgi?file="${file: -27}"'>"${file: -27}"</a><br>";
done;
Now, i want to give the file name as a parameter into a second script, who needs this for reading it.
I found a solution who take the URL parameter and give it into my script
#!/bin/bash
echo "Content-type: text/html"
echo
function cgi_decodevar()
{
[ $# -ne 1 ] && return
local v t h
t="${1//+/ }%%"
while [ ${#t} -gt 0 -a "${t}" != "%" ]; do
v="${v}${t%%\%*}" # digest up to the first %
t="${t#*%}" # remove digested part
if [ ${#t} -gt 0 -a "${t}" != "%" ]; then
h=${t:0:2}
t="${t:2}"
v="${v}"`echo -e \\\\x${h}`
fi
done
echo "${v}"
return
}
function cgi_getvars()
{
[ $# -lt 2 ] && return
local q p k v s
case $1 in
GET)
[ ! -z "${QUERY_STRING}" ] && q="${QUERY_STRING}&"
;;
POST)
cgi_get_POST_vars
[ ! -z "${QUERY_STRING_POST}" ] && q="${QUERY_STRING_POST}&"
;;
BOTH)
[ ! -z "${QUERY_STRING}" ] && q="${QUERY_STRING}&"
cgi_get_POST_vars
[ ! -z "${QUERY_STRING_POST}" ] && q="${q}${QUERY_STRING_POST}&"
;;
esac
shift
s=" $* "
while [ ! -z "$q" ]; do
p="${q%%&*}"
k="${p%%=*}"
v="${p#*=}"
q="${q#$p&*}"
[ "$1" = "ALL" -o "${s/ $k /}" != "$s" ] && \
export "$k"="`cgi_decodevar \"$v\"`"
done
return
}
cgi_getvars BOTH ALL
echo $foo

bash if-statement check for file

I know how to check for a file in bash using this code
file=$1
if [ -f "$file" ]
then
...
fi
But I want to do something when it's not a file.
file=$3
if [ "$1" == "" ] || [ "$2" == "" ] || [ $file is not a file??? ]
then
echo "use: notEmpty notEmpty file"
fi
Can anyone help me out?
if [ "$1" == "" ] || [ "$2" == "" ] || [ ! -f "$file" ]
The whitespaces after [ and before ] are important.

How to use IF loop in unix for multiple conditions

I need a logic to implement the following logic in unix
if ( $a !="xyz" || $d !="abc" ) && ( $b= $c))
then
echo "YES WORKING"
fi
I tried below code not working
if [ [ [ $a != "xyz" ] -o [ $d != "abc" ] ] -a [ "$b" = "$c" ] ]
then
echo "YES WORKING"
fi
getting error as
:[ :] unexpected operator/operand
You can do something like this:
[ $a != "xyz" -o $d != "abc" ] && [ "$b" = "$c" ] && echo "YES WORKING"
Your logic should work easy in shells supporting [[ ]]:
if [[ ($a != "xyz" || $d != "abc") && $b = "$c" ]]; then
echo "YES WORKING"
fi
Although there's a way for those that doesn't:
if ([ ! "$a" = "xyz" ] || [ ! "$d" = "abc" ]) && [ "$b" = "$c" ]; then
echo "YES WORKING"
fi
But that's still inefficient since you'd be summoning subshells, so use { } but the syntax is a little ugly:
if { [ ! "$a" = "xyz" ] || [ ! "$d" = "abc" ]; } && [ "$b" = "$c" ]; then
echo "YES WORKING"
fi

Boolean Expressions in Shell Scripts

What's the "right" way to do the following as a boolean expression?
for i in `ls $1/resources`; do
if [ $i != "database.db" ]
then
if [ $i != "tiles" ]
then
if [ $i != "map.pdf" ]
then
if [ $i != "map.png" ]
then
svn export -q $1/resources/$i ../MyProject/Resources/$i
...
The other solutions have a couple of common mistakes:
http://www.pixelbeat.org/programming/shell_script_mistakes.html
for i in $(ls ...) is redundant/problematic
just do: for i in $1/resources*; do ...
[ $i != file1 -a $1 != file2 ] This actually has 2 problems.
a. The $i is not quoted, hence names with spaces will cause issues
b. -a is inefficient if stating files as it doesn't short circuit (I know the above is not stating files).
So instead try:
for i in $1/resources/*; do
if [ "$i" != "database.db" ] &&
[ "$i" != "tiles" ] &&
[ "$i" != "map.pdf" ] &&
[ "$i" != "map.png" ]; then
svn export -q "$i" "../MyProject/Resources/$(basename $i)"
fi
done
Even shorter:
for i in `ls $1/resources`; do
if [ $i != databse.db -a $i != titles -a $i != map.pdf ]; then
svn export -q $1/resources/$i ../MyProject/Resources/$i
fi
done;
The -a in the if expression is the equivalent of the boolean AND in shell-tests. For more see man test
Consider using a case statement:
for i in $(ls $1/resources); do
case $i in
database.db|tiles|map.pdf|map.png)
;;
*)
svn export -q $1/resources/$i ../MyProject/Resources/$i;;
esac
done
for i in `ls $1/resources`; do
if [ $i != "database.db" ] && [ $i != "tiles" ] && [ $i != "map.pdf" ] && [ $i != "map.png" ]; then
svn export -q $1/resources/$i ../MyProject/Resources/$i
For future reference, the new [[ test operator is preferred. The accepted answer is close and everything mentioned applies, but that answer will require lots of quoting and calls to multiple tests.
The preferred method would be something like:
for i in $1/resources/*; do
if [[ $i != "database.db" && $i != "tiles" &&
$i != "map.pdf" && $i != "map.png" ]]; then
svn export -q "$i" "../MyProject/Resources/$(basename $i)"
fi
done

Resources