Shell Script for modifying desktop.ini file - shell

I have many folders with custom icons. All the folders are present in same directory.
For eg. D:\Folder is the directory which contains folder1, folder2, ..... etc.
And each folder contain their respective icon and desktop.ini files
The contents of current desktop.ini file are as follows:
[.ShellClassInfo]
ConfirmFileOp=0
NoSharing=1
IconFile=folder1.ico
IconIndex=0
InfoTip=folder1
I want to remove NoSharing=1 from each folder's desktop.ini file.
After Removal the ini file should look like :
[.ShellClassInfo]
ConfirmFileOp=0
IconFile=folder1.ico
IconIndex=0
InfoTip=folder1
The ini file is hidden and has attributes : system, hidden and archive.
Thanks for any help you may be able to provide.

Just 1 command: Recursively(-r) replace/remove NoSharing=1 line in each desktop.ini files in D:\Folder
msr -r -p D:\Folder -f "^desktop.ini$" -S -t "(\s+)NoSharing=1\s*" -o "$1" -R
If you want to preview colorful replacing result, remove -R
If you want to backup changed files, add -K like -R -K or -RK
You can also filter by file name, directory name, size range, last write time range, etc., just run the exe to show built-in usages and docs, or see git docs like README.md
msr.exe/msr.gcc*/msr.cygwin is a single exe tool (about 1.6MB, no dependencies, with cross platform versions on Windows and Linux) to find and replace files or pipe text recursively and support backup: in my open project https://github.com/qualiu/msr tools directory.

Use sed to print every line except the unwanted line, on all the filenames, (MS Windows style pathnames), with in-place editing and backup files:
sed --in-place=.bak --quiet '/^NoSharing=1$/!p' D:\Folder\folder?\desktop.ini
(Remove the =.bak if backups aren't needed.)

Related

Mac bash copy all files of one dir to another dir

I have a folder which contains two dirs: build and copy-build.
I need that through bash copy the files that are inside copy-build in build.
If these files already exist it must overwrite them.
I tried with:
cp -r ./SourceFolder ./DestFolder
But the SourceFolder folder is copied into DestFolder, instead I need the SourceFolder files to be copied into DestFolder.
Can you give me a hand?
Assuming there are no subdirectories in SourceDir, you should try
cp ./SourceFolder/* ./DestFolder
See the manual for more info.
Use the -R option instead of -r, and explicitly include a / in the name of the source directory.
cp -R ./SourceFolder/ ./DestFolder
From the description of the -R option:
If the source_file
ends in a /, the contents of the directory are copied rather than
the directory itself.
From the compatibility section of man cp:
Historic versions of the cp utility had a -r option. This implementation
supports that option; however, its use is strongly discouraged, as it
does not correctly copy special files, symbolic links, or fifo's.

Copy command in Mac Terminal fails with "No such file or directory"

This should be straightforward, but I'm getting weird results.
I have a folder with subfolders containing ~4000 files. I'm trying to copy just the files of a certain filetype to another folder, while preserving the subfolder hierarchy.
Command:
cp -R /Users/Steve/Desktop/Hardscapes/*.LOB /Users/Steve/Desktop/Temp
fails with the message:
"/Users/Steve/Desktop/Hardscapes/*.LOB: No such file or directory".
I created the command by typing cp -R then dragging the source folder to the terminal window, adding *.LOB after the /, and dragging the destination folder to the terminal window.
Troubleshooting:
replacing *.LOB with *.* gives the same error.
cp -R /Users/Steve/Desktop/Hardscapes/ /Users/Steve/Desktop/Temp copies the entire Hardscapes folder to Temp, with all its subfolders and files.
Thanks for your help and suggestions.
EDIT: The folder Hardscapes contains only other folders. If I run the command above using one of those folders as the source, the contents are copied faithfully. The folder Hardscapes itself contains no .LOB files - they're only in the subfolders.
So maybe that's the issue, cp can't find any files corresponding to Hardscapes/*.LOB? But I thought the -R switch was supposed to tell it to look through all the subfolders.
Next I put a file named Test.LOB in the Hardscapes folder. The command above copies only that file and none of the subfolders. It looks like the -R switch is not doing its job. Do I have the syntax right?
Try this:
rsync -a --prune-empty-dirs --include '*/' --include '*.LOB' --exclude '*' /Users/Steve/Desktop/Hardscapes/ /Users/Steve/Desktop/Temp
As you already mentioned, directory Hardscapes itself contains no .LOB files. That's why your mask /Users/Steve/Desktop/Hardscapes/*.LOB results in matching no files at all.

How to use Windows Batch File to mass unzip files and saving them in specific folders?

I got the code to mass unzip from this link. But it unzips everything in the folder where the batchfile exists. I want it to unzip it to specific folders or its individual folders.
Note: my bz2 files are in various folders outside the folder where the batchfile exists.
Here's the script that i used :
for /R "C:\Users\victor\Desktop\MASTERS\color feret\disc 1\data\images" %%I in ("*.bz2")
do ("%ProgramFiles%\WinRAR\WinRAR.exe" x -y -o"%%~dpnI" "%%~fI")
Can someone enlighten me how to do it?
And also if possible, can anyone explain to me what are the arguments for? "x , -y -o %%dpnI " etc. Thanks
You do not need a batch file for this process at all. Start WinRAR, select all the archives you want to extract, click on Extract To in toolbar, select the base destination folder, check the option Extract archives to subfolders in Miscellaneous group and press button OK. That's it.
From a command line in a console window with current working directory being the directory containing all the *.bz2 files to extract:
"%ProgramFiles%\WinRAR\WinRar.exe" x -ad -y *.bz2 C:\Temp\
There is no need for a for loop as WinRAR supports wildcards for archive file names.
And with option -ad the archive file First.bz2 is extracted to folder C:\Temp\First, archive file Other.bz2 is extracted to C:\Temp\Other, and so on. With checking option Extract archives to subfolders in GUI, you use option -ad.
Help of WinRAR contains the page Switch -AD - append archive name to destination path. Click in menu Help on Help topics. On tab Contents open Command line mode and open Commands and Switches. Also text file Rar.txt in program files folder of WinRAR contains a description for command x and the options -ad and -y and all other commands and options for console version Rar.exe.
But if you want to use nevertheless a for loop and want to know what %%~dpnI and %%~fI mean, open a command prompt window, enter either help for or for /? and read.

zip all files and folders recursively in bash

I am working on a project, where compilation of the project involves, zipping up various files and folders and subfolders (html/css/js) selectively. Working on the windows platform, and I could continue to just use the CTRL+A and then SHIFT-click to unselect, but it does get a little tedious. I am working with cygwin, so I was wondering if it is possible to issue a command to zip selected files/folders recursively whilst excluding others, in one command? I already have zip command installed, but I seem to be zipping up the current zip file too and the .svn file too.
I would like this to be incorporated into a shell script if possible, so the simpler the better.
After reading the man pages, I think the solution that I was looking for is as follws:
needs to recurse directories (-r),
needs to exclude certail files/directories (-x)
It works in the current directory, but the . can be replaced with the path of any directory
zip -x directories_to_exclude -r codebase_latest.zip .
I have incorporated this into a short shell script that deletes files, tidy up some code, and then zips up all of the files as needed.
You should read man page of zip command:
-R
--recurse-patterns
Travel the directory structure recursively starting at the current directory; for example:
zip -R foo "*.c"
In this case, all the files matching *.c in the tree starting at the current directory are stored into a zip archive named foo.zip. Note that *.c will match
file.c, a/file.c and a/b/.c. More than one pattern can be listed as separate arguments. Note for PKZIP users: the equivalent command is
pkzip -rP foo *.c
Patterns are relative file paths as they appear in the archive, or will after zipping, and can have optional wildcards in them. For example, given the cur‐
rent directory is foo and under it are directories foo1 and foo2 and in foo1 is the file bar.c,
zip -R foo/*
will zip up foo, foo/foo1, foo/foo1/bar.c, and foo/foo2.
zip -R */bar.c
will zip up foo/foo1/bar.c. See the note for -r on escaping wildcards.
You can also have a look HERE

Mac zip compress without __MACOSX folder?

When I compress files with the built in zip compressor in Mac OSX, it causes an extra folder titled "__MACOSX" to be created in the extracted zip.
Can I adjust my settings to keep this folder from being created or do I need to purchase a third party compression tool?
UPDATE: I just found a freeware app for OSX that solves my problem: "YemuZip"
UPDATE 2: YemuZip is no longer freeware.
Can be fixed after the fact by zip -d filename.zip __MACOSX/\*
And, to also delete .DS_Store files: zip -d filename.zip \*/.DS_Store
When I had this problem I've done it from command line:
zip file.zip uncompressed
EDIT, after many downvotes: I was using this option for some time ago and I don't know where I learnt it, so I can't give you a better explanation. Chris Johnson's answer is correct, but I won't delete mine. As one comment says, it's more accurate to what OP is asking, as it compress without those files, instead of removing them from a compressed file. I find it easier to remember, too.
Inside the folder you want to be compressed, in terminal:
zip -r -X Archive.zip *
Where -X means: Exclude those invisible Mac resource files such as “_MACOSX” or “._Filename” and .ds store files
source
Note: Will only work for the folder and subsequent folder tree you are in and has to have the * wildcard.
This command did it for me:
zip -r Target.zip Source -x "*.DS_Store"
Target.zip is the zip file to create. Source is the source file/folder to zip up. The -x parameter specifies the file/folder to exclude.
If the above doesn't work for whatever reason, try this instead:
zip -r Target.zip Source -x "*.DS_Store" -x "__MACOSX"
I'm using this Automator Shell Script to fix it after.
It's showing up as contextual menu item (right clicking on any file showing up in Finder).
while read -r p; do
zip -d "$p" __MACOSX/\* || true
zip -d "$p" \*/.DS_Store || true
done
Create a new Service with Automator
Select "Files and Folders" in "Finder"
Add a "Shell Script Action"
zip -r "$destFileName.zip" "$srcFileName" -x "*/\__MACOSX" -x "*/\.*"
-x "*/\__MACOSX": ignore __MACOSX as you mention.
-x "*/\.*": ignore any hidden file, such as .DS_Store .
Quote the variable to avoid file if it's named with SPACE.
Also, you can build Automator Service to make it easily to use in Finder.
Check link below to see detail if you need.
Github
The unwanted folders can be also be deleted by the following way:
zip -d filename.zip "__MACOSX*"
Works best for me
The zip command line utility never creates a __MACOSX directory, so you can just run a command like this:
zip directory.zip -x \*.DS_Store -r directory
In the output below, a.zip which I created with the zip command line utility does not contain a __MACOSX directory, but a 2.zip which I created from Finder does.
$ touch a
$ xattr -w somekey somevalue a
$ zip a.zip a
adding: a (stored 0%)
$ unzip -l a.zip
Archive: a.zip
Length Date Time Name
-------- ---- ---- ----
0 01-02-16 20:29 a
-------- -------
0 1 file
$ unzip -l a\ 2.zip # I created `a 2.zip` from Finder before this
Archive: a 2.zip
Length Date Time Name
-------- ---- ---- ----
0 01-02-16 20:29 a
0 01-02-16 20:31 __MACOSX/
149 01-02-16 20:29 __MACOSX/._a
-------- -------
149 3 files
-x .DS_Store does not exclude .DS_Store files inside directories but -x \*.DS_Store does.
The top level file of a zip archive with multiple files should usually be a single directory, because if it is not, some unarchiving utilites (like unzip and 7z, but not Archive Utility, The Unarchiver, unar, or dtrx) do not create a containing directory for the files when the archive is extracted, which often makes the files difficult to find, and if multiple archives like that are extracted at the same time, it can be difficult to tell which files belong to which archive.
Archive Utility only creates a __MACOSX directory when you create an archive where at least one file contains metadata such as extended attributes, file flags, or a resource fork. The __MACOSX directory contains AppleDouble files whose filename starts with ._ that are used to store OS X-specific metadata. The zip command line utility discards metadata such as extended attributes, file flags, and resource forks, which also means that metadata such as tags is lost, and that aliases stop working, because the information in an alias file is stored in a resource fork.
Normally you can just discard the OS X-specific metadata, but to see what metadata files contain, you can use xattr -l. xattr also includes resource forks and file flags, because even though they are not actually stored as extended attributes, they can be accessed through the extended attributes interface. Both Archive Utility and the zip command line utility discard ACLs.
You can't.
But what you can do is delete those unwanted folders after zipping. Command line zip takes different arguments where one, the -d, is for deleting contents based on a regex. So you can use it like this:
zip -d filename.zip __MACOSX/\*
Cleanup .zip from .DS_Store and __MACOSX, including subfolders:
zip -d archive.zip '__MACOSX/*' '*/__MACOSX/*' .DS_Store '*/.DS_Store'
Walkthrough:
Create .zip as usual by right-clicking on the file (or folder) and selecting "Compress ..."
Open Terminal app (search Terminal in Spotlight search)
Type zip in the Terminal (but don't hit enter)
Drag .zip to the Terminal so it converts to the path
Copy paste -d '__MACOSX/*' '*/__MACOSX/*' .DS_Store '*/.DS_Store'
Hit enter
Use zipinfo archive.zip to list files inside, to check (optional)
I have a better solution after read all of the existed answers. Everything could done by a workflow in a single right click.
NO additional software, NO complicated command line stuffs and NO shell tricks.
The automator workflow:
Input: files or folders from any application.
Step 1: Create Archive, the system builtin with default parameters.
Step 2: Run Shell command, with input as parameters. Copy command below.
zip -d "$#" "__MACOSX/*" || true
zip -d "$#" "*/.DS_Store" || true
Save it and we are done! Just right click folder or bulk of files and choose workflow from services menu. Archive with no metadata will be created alongside.
IMAGE UPDATE: I chose "Quick Action" when creating a new workflow - here’s an English version of the screenshot:
do not zip any hidden file:
zip newzipname filename.any -x "\.*"
with this question, it should be like:
zip newzipname filename.any -x "\__MACOSX"
It must be said, though, zip command runs in terminal just compressing the file, it does not compress any others. So do this the result is the same:
zip newzipname filename.any
Keka does this. Just drag your directory over the app screen.
Do you mean the zip command-line tool or the Finder's Compress command?
For zip, you can try the --data-fork option. If that doesn't do it, you might try --no-extra, although that seems to ignore other file metadata that might be valuable, like uid/gid and file times.
For the Finder's Compress command, I don't believe there are any options to control its behavior. It's for the simple case.
The other tool, and maybe the one that the Finder actually uses under the hood, is ditto. With the -c -k options, it creates zip archives. With this tool, you can experiment with --norsrc, --noextattr, --noqtn, --noacl and/or simply leave off the --sequesterRsrc option (which, according to the man page, may be responsible for the __MACOSX subdirectory). Although, perhaps the absence of --sequesterRsrc simply means to use AppleDouble format, which would create ._ files all over the place instead of one __MACOSX directory.
This is how i avoid the __MACOSX directory when compress files with tar command:
$ cd dir-you-want-to-archive
$ find . | xargs xattr -l # <- list all files with special xattr attributes
...
./conf/clamav: com.apple.quarantine: 0083;5a9018b1;Safari;9DCAFF33-C7F5-4848-9A87-5E061E5E2D55
./conf/global: com.apple.quarantine: 0083;5a9018b1;Safari;9DCAFF33-C7F5-4848-9A87-5E061E5E2D55
./conf/web_server: com.apple.quarantine: 0083;5a9018b1;Safari;9DCAFF33-C7F5-4848-9A87-5E061E5E2D55
Delete the attribute first:
find . | xargs xattr -d com.apple.quarantine
Run find . | xargs xattr -l again, make sure no any file has the xattr attribute. then you're good to go:
tar cjvf file.tar.bz2 dir
Another shell script that could be used with the Automator tool (see also benedikt's answer on how to create the script) is:
while read -r f; do
d="$(dirname "$f")"
n="$(basename "$f")"
cd "$d"
zip "$n.zip" -x \*.DS_Store -r "$n"
done
The difference here is that this code directly compresses selected folders without macOS specific files (and not first compressing and afterwards deleting).

Resources