Replace item in zipped (sub) folder

I need to replace one document in an existing zipped file.

This are the steps I think they are necessary:

  1. first search the zipped file in the (sub)folders
  2. unzipped file
  3. replace the document
  4. zip the file (without .ds_store)

I already could made the script without unzipping/zipping the file.
Does anyone can help me to add this part to my script?


set main_folder to (choose folder with prompt "Choose the workfolder")
set main_file to (choose file with prompt "Choose the new file?")
set Zipped_file to display dialog "Name of zipfile" default answer "" buttons {"OK"} default button "OK"
set text_user_entered to the text returned of Zipped_file
log text_user_entered

tell application "Finder"
	
	set sub_folders to folders of main_folder
	repeat with i from 1 to count sub_folders
		set sub_sub_folders to every document file of item i of sub_folders
		repeat with j from 1 to count sub_sub_folders
			set subName to name of item j of sub_sub_folders
			
			if subName is text_user_entered then
			else
				
				--unzip folder
				--duplicate main_file to item j of sub_sub_folders with replacing
				-- zip folder (without .DS_store)
				
			end if
		end repeat
		
	end repeat
	
end tell

Is there some logic behind choosing the parent folder and then searching for a subfolder name that a user types (lots of errors there) rather than just choose the folder you want to unzip in step 1?

I hope there is a logic :slight_smile:

We have one folder with 70 subfolders. In each subfolder exist several subfolder, one of them is Package.zip. Now we have to change one of files in Package.zip and this in all the subfolders. And yes each Package.zip is different.

If there is a better way to do replace this file in all of the package.zip, feel free :slight_smile: (I am just a beginner in applescript)

They are all named Package.zip ?

I agree with adayzdone, assuming you have the file open in some app when you know you are done editing it:

Wouldn’t it then be better to reveal the file by the proxy icon, and then run the script by using the current selection in the front finder window?

from there you could use a do shell script that returns the first zipfile with the name of the current folder. (man find)

Then you could execute zip ”r ziparchieve filetoupdate. (man zip)

I am as interested as you to find a way to ignore the .DS_Store files when doing archievieving with zip as of today
I use something like this to strip the zip-files for Mac Os X specific contents:


property scriptTitle : "Cross platform arcieve"
-- © McUsr 2012 and Put in public domain 
-- you may not post this elsewhere nor put it in a publicly accessible repository 
-- but refer to this link: http://macscripter.net/viewtopic.php?pid=156380#p156380
on run
	local a, b, c -- as in school ;)
	set b to {}
	try
		tell application "Finder"
			-- your code goes here...
			set c to its selection
			set b to count c
			repeat with a in c
				makeCrossPlattformArchieve of me for (a as alias)
			end repeat
			
			if b > 0 then
			else
				error "You have to select some zip archieves for this to work" number 3000
			end if
		end tell
	on error e number n
		tell application "SystemUIServer"
			activate
			display dialog e with title scriptTitle buttons {"Ok"} default button 1
		end tell
	end try
end run
to makeCrossPlattformArchieve for aFileAlias
	local pxFn, pf, fn, s
	set pxFn to POSIX path of aFileAlias as text
	set {pf, fn, s} to splitPxFile for pxFn
	if s = "zip" then
		do shell script "zip -dr " & quoted form of pxFn & "  __MACOSX/\\*  >/dev/null ; unzip -l " & quoted form of pxFn & "  |grep \".DS_Store\" | tr -s \" \"  |cut -d \" \" -f 5-20 |zip -d " & quoted form of pxFn & " -@ >/dev/null ||echo >/dev/null"
	else
		error "We only process zip files!
 " & pxFn number 3000
	end if
end makeCrossPlattformArchieve

to splitPxFile for pxPath
	-- http://macscripter.net/viewtopic.php?id=39332
	local ppl, sl, s, tids, f
	set ppl to length of pxPath
	set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "."}
	
	set s to item -1 of text items of pxPath
	set sl to length of s
	if sl = ppl then
		set s to missing value
		set pxPath to text items 1 thru -1 of pxPath as text
	else
		set pxPath to text items 1 thru -2 of pxPath as text
	end if
	set AppleScript's text item delimiters to "/"
	
	set f to item -1 of text items of pxPath
	if f = "" then set f to missing value
	try
		set pxPath to (items 1 thru -2 of text items of pxPath)
		set pxPath to (pxPath as text) & "/"
	on error
		set pxPath to missing value
	end try
	set AppleScript's text item delimiters to tids
	return {pxPath, f, s}
end splitPxFile

@adyzone

yes they are all named Package

Don’t shoot me, I am just the pianist. My colleagues made the structure and now they have this problem. I’ve tried to make some scripts, so they thought I could make one for them… :frowning:

@McUsr

I will check your post… :slight_smile:

@McUsr

Wow… I just tried your script. It works really really fine…

Is it possible to replace a file during the do shell script?

do shell script is a command in AppleScript Script additions.

if you stuff into it, zip -r, the correct quoted form of posix path of the archieve, and the filename, it is best to cd to the folder by which the file you want to replace resides in. Then it should work. Something like this.


set zip_arc to quoted form of POSIX path of (path to desktop folder as text) & "test.zip"
set ftorep to (path to desktop folder as text) & "test.txt"
tell application "System Events"
   set theFol to POSIX path of (container of disk item ftorep)
end tell
set ftorep to quoted form of POSIX path of ftorep
do shell script "cd  " & quoted form of theFol & " &&  zip -r " & zip_arc & " " & ftorep

The find command goes like this:


set arc2f to "test.zip"

set ftorep to (path to desktop folder as text) & "test.txt"
tell application "System Events"
	set theFol to POSIX path of (container of disk item ftorep)
end tell
set ftorep to quoted form of POSIX path of ftorep
set theARc to (do shell script "find " & theFol & " -name " & arc2f & " 2>/dev/null")



Does this work?

set main_folder to (choose folder with prompt "Choose the workfolder")
set main_file to (choose file with prompt "Choose the new file?")
set main_file to quoted form of (POSIX path of main_file)
set text_user_entered to text returned of (display dialog "Name of zipfile" default answer "" buttons {"OK"} default button "OK")
log text_user_entered
with timeout of 360 seconds
	tell application "Finder" to set zipFiles to every item of entire contents of main_folder whose name is text_user_entered
end timeout
repeat with aFile in zipFiles
	set aFile to quoted form of (POSIX path of (aFile as alias))
	do shell script "zip -j " & aFile & space & main_file
end repeat

This works… I am sure it isn’t the best way…

How can I delete the .DS_store in the do shell script?


set main_folder to (choose folder with prompt "Choose the workfolder")
set main_file to (choose file with prompt "Choose the new file?")
set Zipped_file to display dialog "Name of zipfile (without .zip)" default answer "" buttons {"OK"} default button "OK"
set text_user_entered to the text returned of Zipped_file
log text_user_entered

tell application "Finder"
	
	set sub_folders to folders of main_folder
	repeat with i from 1 to count sub_folders
		set sub_sub_folders to every document file of item i of sub_folders
		repeat with j from 1 to count sub_sub_folders
			set subName to name of item j of sub_sub_folders
			if subName is (text_user_entered & ".zip") then
				open item j of sub_sub_folders
				delay 1
			end if
			set NewFolder to every folder of item i of sub_folders
			repeat with k from 1 to count NewFolder
				set NewName to name of item k of NewFolder
				log NewName
				if NewName is text_user_entered then
					duplicate main_file to item k of NewFolder with replacing
				end if
				set theItem to (item k of NewFolder) as alias
				set itemPath to quoted form of POSIX path of theItem
				set fileName to name of theItem
				set theFolder to POSIX path of (container of theItem as alias)
				set zipFile to quoted form of (theFolder & fileName & ".zip")
				do shell script "zip -r " & zipFile & " " & itemPath
				delete theItem
			end repeat
		end repeat
	end repeat
end tell


it seems it did work… but it didn’t… . :frowning: :frowning: :frowning:

If I read well, zipFile is the path to the zipped item and itemPath is the path to the item to zip.
If I’m right, it would be more efficient to write :

do shell script "zip -r " & itemPath & " " & zipFile

Yvan KOENIG (VALLAURIS, France) mercredi 10 octobre 2012 17:41:52

Hello.

Unless someone comes up with the right curse for writing a zip archieve without storing Mac Os X resource files stored, then I think the only option is to delete it afterwards.

You can use this as a starting point, and play with it in a terminal window. This line was made for archieves not using the -j option (junk paths) so it works when the path is stored within the zip file. pxFn is the quoted form of posix path to the archieve.


do shell script "unzip -l " & quoted form of pxFn & " |grep \".DS_Store\" | tr -s \" \" |cut -d \" \" -f 5-20 |zip -d " & quoted form of pxFn & " -@ >/dev/null ||echo >/dev/null"

(1) I must apologize.
The answer posted in message #12 is wrong.

My memory gave the syntax required by ditto which is the reverse of the one required by zip.

(2) I ran this script :


set theSource to (path to desktop as text) & "remplacés ƒ:"
tell application "System Events"
	set theZip to path of container of disk item theSource & "beurk.zip"
end tell
set dsStore to theSource & ".DS_Store"
try
	do shell script "rm " & quoted form of POSIX path of dsStore
end try
do shell script "ditto -ck " & quoted form of POSIX path of theSource & space & quoted form of POSIX path of theZip

There was a .DS_Store file in the source folder.
There is no such file in the folder beurk which I got after expanding the beurk.zip file.

My understanding is that removing the hidden file thru a shell script and packing it immediately doesn’t give the Finder the ability to recreate the infamous item.

In fact, I guess that using rm to delete the hidden item was unneeded.


set theSource to (path to desktop as text) & "remplacés ƒ:"
tell application "System Events"
	set theZip to path of container of disk item theSource & "beurk.zip"
	try
		delete disk item (theSource & ".DS_Store")
	end try
end tell
do shell script "ditto -ck " & quoted form of POSIX path of theSource & space & quoted form of POSIX path of theZip

was able to do the trick.

Yvan KOENIG (VALLAURIS, France) mercredi 10 octobre 2012 19:03:44

Hello!

Now, deleting .DS_Store :wink: -That was another approach! I like .DS_Store everywhere, except when I have to share files with people on other platforms.

By the way, and the sad excuse for posting this post: Here is a nice new monospaced free font from Adobe. The otf version should easily be imported into fontbook! I have replaced deja vu with it.

Announcing Source Code Pro « Typblography

Does anyone get .DS_Store files with my script in #9 ? I’m not clear where this doesn’t work.

I actually got “Apple Event timed out”, from the finder command that should find all the zip archieves.

So I couldn’t check it. And the reason is that I checked it on the Desktop, and my Desktop is cluttered at the moment. :slight_smile:

I ripped out the repeat loop and finder, and hardcoded it, and nope, there where no .DS_Store file there.

I also realized, that when you unzip a file, where a default application are set for the file type, you loose it.

Now I wonder, if that kind of information is stored in the .DS_Store file.

entire contents could take a long time.
Events sent to applications time out after 120 secs.
You can prolong the interval with a timeout block

Post #9 updated to reflect StefanK’s suggestion. Thanks.

I know, I actually code my dialogs with a “giving up after”, and made it work by inserting a block around them with timeout. :slight_smile: (When giving up later than 2 minutes.)

I actually prefer do shell script "find . " over Finder if I am to search a subtree for files. This timed out, and I have an SDD disk, what gives?

Edit
And just for the record.

The second the zip file is unextracted, a new .DS_Store file will be recreated. To see if the zipfile has a .DS_Store file in it you should do an unzip -l zipfile in a terminal window.