Adding Swift files to Xcode project dynamically using a shell script with a more general path - xcode

I'm trying to add .swift files dynamically to an Xcode project using a shell script. The script works fine, but it requires me to specify the exact location of the project.pbxproj file. The problem is, the location of the project file may vary across different machines, which makes it difficult to maintain the script.
One potential solution to this problem is to use a more general approach to get the path to the project file. Another issue I encountered is that the script adds the new files to the end of the project.pbxproj file, which can cause the file to become corrupted.
I have updated the script to use a different approach that should work better:
#!/bin/bash
# Define the directory where the script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
# Define the source directory
SOURCE_DIR="$SCRIPT_DIR/YourSourceDirectory"
# Find the Xcode project directory by searching for *.xcodeproj in the parent directory
PROJECT_DIR="$(find "$SCRIPT_DIR"/.. -name '*.xcodeproj' -maxdepth 1 -print -quit)"
if [[ -z "$PROJECT_DIR" ]]; then
echo "Could not find Xcode project directory"
exit 1
fi
# Get the path to the project.pbxproj file
PROJECT_FILE="$PROJECT_DIR/project.pbxproj"
# Change to the source directory
cd "$SOURCE_DIR"
# Loop through all the files in the directory and add them to the Xcode project
for file in *.swift; do
# Check if the file is already in the Xcode project
if ! grep -q "$file" "$PROJECT_FILE"; then
# Add the file to the Xcode project
echo "Adding file $file to Xcode project"
FILE_ID=$(uuidgen)
echo "/* $file */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = $file; sourceTree = \"<group>\"; }; $FILE_ID /* $file */ = {isa = PBXBuildFile; fileRef = $FILE_ID /* $file */; }; " >> "$PROJECT_FILE"
fi
done
# Remove any files from the Xcode project that are not in the source directory
for file in "$PROJECT_DIR"/*.swift; do
if [[ ! -f "$SOURCE_DIR/$(basename "$file")" ]]; then
# Remove the file from the Xcode project
echo "Removing file $(basename "$file") from Xcode project"
FILE_ID=$(grep -B 1 "$(basename "$file")" "$PROJECT_FILE" | awk -F '[ /]+' '/^\/\* / {print $(NF-1)}')
if [[ ! -z "$FILE_ID" ]]; then
sed -i '' "/$FILE_ID/d" "$PROJECT_FILE"
fi
fi
done
Input Files = $SOURCE_DIR/*.swift
Output Files = $PROJECT_DIR/project.pbxproj
This updated script first searches for the Xcode project directory by looking for *.xcodeproj in the parent directory. It then gets the path to the project.pbxproj file and uses it to add the new files to the project.
To avoid corrupting the project.pbxproj file, the script creates new PBXFileReference and PBXBuildFile entries for each new file, instead of adding them to the end of the file. The script also removes any files from the project that are not in the source directory.
I hope this helps!

Related

Create folders with filenames and move files into folder

I have a bunch of files that end with .EHZ and I am trying to create a folder for each of these files and then move them into the corresponding folders. Also the files have a Z attached to the name that I would like to remove. So ideally i would have, for example these files
AAAAZBBBBZ.EHZ
CCCCZDDDDZ.EHZ
EEEEZFFFFZ.EHZ
Turn into the folders
AAAABBBB
CCCCDDDD
EEEEFFFF
What I have written so far is
dir0=pwd
for file in `ls *.EHZ`
do
name=echo $file | head 10
mkdir -p $name
mv "$file" "$name"
done
P.S. I have found many answers in stackoverflow that were addressed to this issue but not on shell so I figured I would ask.
Could you please try following. I have used cp command for safer side in my code, you could remove it and put it as mv in there to actually move files to folders.
for file in *.EHZ
do
name="${file%.*}"
actual_directory_name="${name::-1}"
if [[ ! -d "$actual_directory_name" ]]
then
mkdir "$actual_directory_name"
fi
cp "$file" "$actual_directory_name"
if [[ -s "$actual_directory_name/$file" ]]
then
echo "$file is moved Successfully to directory name $actual_directory_name now.."
else
echo "Please check seems $file is NOT moved to directory $actual_directory_name."
fi
done

Find operator can't go up in directory?

I'm trying to list all files of a directory that not exist in another.
And the script tells me:
find: ‘ (...) /nanorc/../original/*’: No such file or directory
Where is the problem? Thanks!
Code:
# todo: list all files that isn't in original folder
# get a file in nanorc folder
# try to find it in the ../original folder
# if there isn't, list it.
cd nanorc/
for file in *; do
[ -e "$file" ] || continue
# if [ -z $(find "$(pwd)/../original/*" -name "$file") ]; then
if [ -z $(find $(pwd)/../original/* -name "$file") ]; then
lite=`printf "%s %s" "$lite" "$file"`
fi
done
cd ..
echo "$lite
Notes:
The script must be POSIX complaint.
I tried various variations of find, like: "../original", "../original/*",...
I don't want to create files; the script should populate one variable after the checks.
Solution:
Just put out the "".
To check if a file exists use test -e.
if [ ! -e "../original/$file" ]; then
echo "File ../original/$file does not exists"
fi
Path are by default searched in current working directory, there is no need to use $(pwd).
The error in your script came from "$(pwd)/../original/*" - the * is inside " so it does not expand. You could change it to "../original/"*, but because find works recursively, just find ../original.

Match and copy the contents of the same directory name to a new directory with the same name?

My script should check a directory called /etc/scriptbuilder/default/contents which will hold some directories, if a directory in the contents directory matches one in the project directory the files in the contents directory should be copied to the project directory (so, if /etc/scriptbuilder/default/contents/docs and /project/docs both exist, the contents of /etc/scriptbuilder/default/contents/docs should be copied).
I'm having trouble making this work. It has to find a match of the same directory name and copy the contents over from the contents directory to the project directory if they have the same directory name. This is what I have so far:
#! /bin/bash
if [ -d "$/etc/scriptbuilder/default/contents ]; then
if [[ "/etc/scriptbuilder/default/contents" =~ name ]]; then
cp -a #I'm not sure how to copy and check for the name on the project
directory
fi
fi
Something like that finds the the directories you are looking for and prints them.
source="/etc/scriptbuilder/default/contents"
destination="/home/something/project"
# loop the directories of the source folder
cd "$source"
for name in */ ; do
# create the source and the possible destination directory paths
s="$source/$name"
d="$destination/$name"
# check if the directory exists in the project
if [ -d "$d" ]; then
echo "TODO: Perfrom copy of from $s to $d"
fi
done
If you need help with copy command also post a comment.
With loop it could be like this:
Dir1=path_to_contents/contents
Dir2=path_to_project/project
for i in $(find "$Dir1/" "$Dir2/" -printf '%P\n' | sort | uniq -d)
do
cp -r $Dir1/$i $Dir2
done

Exclude files from being downloaded

Im using a server. Id like to sync files with my home PC. Unfortunally there is no app that could remember what files was previously downloaded - so if the file is moved from the "incoming" folder, it will be redownloaded from the server.
Ive found a app (goodsync) that is able to run a script or batch pre-download. So I was thinking, Ill run a script in advance that writes all the filenames to a .txt according this -> http://stackoverflow.com/questions/8612324/is-this-possible-to-write-list-of-file-names-into-a-text-file-using-batch-file-w
So, how to script or batch something like "check what´s in C:\exclude.txt and dont download files with the exact same name"
Okay here's a little shell script which can be used to read which files are already downloaded, reads which files exist and then checks which files should be downloaded. But I recommend you to learn shell scripting to understand the script and to make the script better.
Basically what this code does is reading the downloaded.txt (or exclude.txt) file (Every line should containt filename and hash concatenated).
Then it reads all files from the file system and checks if the file is contained in the downloaded.txt file.
If the file is not contained in the downloaded.txt file you can decide what you would like to do.
you could create a new textfile which contains the files you have to
download.
you could add the files found to downloaded.txt (but use the searched variable because it contains the hash and the filename) and download these files.
found=0
array_contains () {
local array="$1[#]"
local seeking=$2
found=0
for element in "${!array}"; do
if [[ $element == $seeking ]]; then
found=1
break
fi
done
}
downloaded_files=()
#Load the downloaded files from downloaded.txt into the downloaded_files array
old_IFS=$IFS # save the field separator
IFS=$'\n' # new field separator, the end of line
for line in $(cat downloaded.txt)
do
downloaded_files=("${downloaded_files[#]}" "$line")
done
#print the whole array just for testing
echo ${downloaded_files[#]}
filehashlist=($(find * -type f -exec sha1sum "{}" \; | cut -d ' ' -f 1))
filenamelist=($(find * -type f -exec basename "{}" \;))
filenamelistFullPath=($(find * -type f))
to_download_files=()
counter=0
for filename in "${filenamelist[#]}"
do
searched=$filename${filehashlist[$counter]}
array_contains downloaded_files "$searched"
if [ $found == "0" ]; then
echo "Please download file: $filename"
echo "Location: ${filenamelistFullPath[$counter]}"
echo "Hash: ${filehashlist[$counter]}"
echo "Add this line to downloaded.txt after download: $searched"
echo ""
fi
counter=$counter+1
done
IFS=$old_IFS # restore default field separator
From command line or .CMD script:
xcopy /D /E /F /Y /EXCLUDE:exclude.txt
where exclude.txt is the file you mentioned containing your list of filenames to be excluded

Shell script to add text at the end of Directory and specific files

I need some help with writing a Bash script. I have tried a lot but can't figure out how to finish it and I am new to programming.
I want to create a script that will take a parameter that should be a sub-directory of the current directory.
And then find if the parameter is a file or directory.
If it is a directory it should just add the extension text at the end of the name of the found directory DDD.
And if it is a file that has the following extension 'mpg or wmv or mov', it should add at the end of the same extension as the file extension at the end of the file name.
Example:
If the file name is: hello.mov, it will be renamed as hello.mov.mov
My Script:
#!/bin/bash
for file in ./$*
do
find ./$1 -maxdepth 1
if [ -d $file ]
?????????
fi
for ext in avi mpg wmv mov;
do
?????????????????
#!/bin/bash
for file in ./* # */ This comment here just to fix broken syntax highlighting
do
if [[ -d $file ]]
then
ext=DDD
else
ext="${file##*.}" # Get extension
fi
mv "${file}" "${file}.$ext" # Rename file to $file + . + $ext
done

Resources