macOS Terminal Run a Command on Each File in a Directory - macos

I need to run this command:
xattr -d com.apple.FinderInfo '*filenamehere*' && xattr -d com.apple.metadata:_kMDItemUserTags '*filenamehere*'
...on these files (all in the same directory):
2021-11-19 at 21-42-10.jpg
2021-11-19 at 21-37-23.jpg
2021-11-19 at 21-37-05.jpg
2021-11-19 at 21-34-09.jpg
2021-11-19 at 21-33-58.jpg
2021-11-19 at 21-33-44.jpg
2021-11-19 at 21-33-28.jpg
2021-11-19 at 21-33-22.jpg
For example:
xattr -d com.apple.FinderInfo '2021-11-19 at 21-33-22.jpg' && xattr -d com.apple.metadata:_kMDItemUserTags '2021-11-19 at 21-33-22.jpg'
xattr -d com.apple.FinderInfo '2021-11-19 at 21-33-28.jpg' && xattr -d com.apple.metadata:_kMDItemUserTags '2021-11-19 at 21-33-28.jpg'
xattr -d com.apple.FinderInfo '2021-11-19 at 21-33-44.jpg' && xattr -d com.apple.metadata:_kMDItemUserTags '2021-11-19 at 21-33-44.jpg'
etc.
Instead of manually specifying each file name and running its command individually, is there a way to modify this command to run on every file in this directory?

Related

How to get list of the files in a folder in gitlab-ci

I am trying to create a pipeline in gitlab-ci. my problem is that when I run ls command I can see my files, but when I use for condition, I cannot find same files. any suggestion?
script:
- set -vux
- ls ./dist/*
- |
for file in ./dist/*; do
if [ -f ${file} ]; then
export ARTIFACTORY_IMAGE_TAG=${DATASCIENCE_REPO}/$(basename ${file})/$IMAGE_VERSION
'curl -H "X-JFrog-Art-Api: $ARTIFACTORY_PW" -XPUT "$ARTIFACTORY_IMAGE_TAG" -T dist/$file'
fi
done
dependencies:
- package-build
my output is like this:
$ ls ./dist/*
ls ./dist/*
++ ls ./dist/__init__.py ./dist/my_proj-0.0.1.1164649-py3-none-any.whl ./dist/file1.py ./dist/file2.py ./dist/file3.json ./dist/file4.json
./dist/__init__.py
./dist/my_proj-0.0.1.1164649-py3-none-any.whl
./dist/file1.py
./dist/file2.py
./dist/file3.json
./dist/file4.json
echo $'\x1b[32;1m$ for file in ./dist/*; do # collapsed multi-line command\x1b[0;m'
++ echo '$ for file in ./dist/*; do # collapsed multi-line command'
$ for file in ./dist/*; do # collapsed multi-line command
for file in ./dist/*; do
if [ -f ${file} ]; then
export ARTIFACTORY_IMAGE_TAG=${MY_REPO}/$(basename ${file})/$IMAGE_VERSION
'curl -H "X-JFrog-Art-Api: $ARTIFACTORY_PW" -XPUT "$ARTIFACTORY_IMAGE_TAG" -T dist/$file'
fi
done
++ for file in ./dist/*
++ '[' -f ./dist/__init__.py ']'
+++ basename ./dist/__init__.py
++ export ARTIFACTORY_IMAGE_TAG=https://artifactory.xyz.com/artifactory/my_proj_dev/__init__.py/0.0.1.1164649
++ ARTIFACTORY_IMAGE_TAG=https://artifactory.xyz.com/artifactory/my_proj_dev/__init__.py/0.0.1.1164649
++ 'curl -H "X-JFrog-Art-Api: $ARTIFACTORY_PW" -XPUT "$ARTIFACTORY_IMAGE_TAG" -T dist/$file'
/scripts-11718-6374270/step_script: line 239: curl -H "X-JFrog-Art-Api: $ARTIFACTORY_PW" -XPUT "$ARTIFACTORY_IMAGE_TAG" -T dist/$file: No such file or directory
Cleaning up project directory and file based variables
00:00
ERROR: Job failed: command terminated with exit code 1
Update 1: according to the error I am receiving, I think in my curl command system cannot file the file. but why I am not sure?
Simple syntax mistake.
The error says there is No such file or directory.
line 239: curl -H "X-JFrog-Art-Api: $ARTIFACTORY_PW" -XPUT "$ARTIFACTORY_IMAGE_TAG" -T dist/$file: No such file or directory
An experiment.
Let's run these three commands in your terminal.
The first one
(DO NOT REMOVE A SINGLE QUOTE.)
'touch love and peace'
The result is in bash
-bash: touch love and peace: command not found
The result is in zsh
zsh: command not found: touch love and peace
A terminal recognizes the single-quoted string as a command in the first command.
The second one
(DO NOT REMOVE A SINGLE QUOTE.)
'touch /'
The result is in bash
-bash: touch /: No such file or directory
The result is in zsh
zsh: no such file or directory: touch /
A terminal recognizes the single-quoted string with the slash as a file in the second command.
The third one
without a single quote.
touch love and peace
The result is
$ls
and love peace
If you intend to run the curl command in every loops,
Just remove the single quotes.
curl -H "X-JFrog-Art-Api: $ARTIFACTORY_PW" -XPUT "$ARTIFACTORY_IMAGE_TAG" -T $file
The solution
for file in ./dist/*; do
if [ -f ${file} ]; then
export ARTIFACTORY_IMAGE_TAG=${DATASCIENCE_REPO}/$(basename ${file})/$IMAGE_VERSION
curl -H "X-JFrog-Art-Api: $ARTIFACTORY_PW" -XPUT "$ARTIFACTORY_IMAGE_TAG" -T $file
fi
done
It seems like the problem is that you are not listing the files in your for statement. Try:
for file in `ls ./dist/*`; do
echo "act on $file"
done

Pass stdin to plistbuddy

I have a script to show the content of the Info.plist of .ipa files:
myTmpDir=`mktemp -d 2>/dev/null || mktemp -d -t 'myTmpDir'`
unzip -q "$1" -d "${myTmpDir}";
pathToFile=${myTmpDir}/Payload/*.app/Info.plist
/usr/libexec/PlistBuddy -c "Print" ${pathToFile}
With large files this can take some time until they are extracted to the temp folder just to read a small Info.plist (xml) file.
I wondered if I can just extract Info.plist file and pass that to plistbuddy? I've tried:
/usr/libexec/PlistBuddy -c "Print" /dev/stdin <<< \
$(unzip -qp test.ipa Payload/*.app/Info.plist)
but this yields
Unexpected character b at line 1
Error Reading File: /dev/stdin
The extraction is working fine. When running unzip -qp test.ipa Payload/*.app/Info.plist I get the output of the Info.plist file to the terminal:
$ unzip -qp test.ipa Payload/*.app/Info.plist
bplist00?&
!"#$%&'()*+5:;*<=>?ABCDECFGHIJKXYjmwxyIN}~N_BuildMachineOSBuild_CFBundleDevelopm...
How can I pass the content of the Info.plist to plistbuddy?
Usually commands support "-" as a synonym of stdin, but this PlistBuddy tool doesn't.
But you can still extract just one file from your ipa, save it as a temporary file, and then run PlistBuddy on that file:
tempPlist="$(mktemp)"
unzip -qp test.ipa "Payload/*.app/Info.plist" > "$tempPlist"
/usr/libexec/PlistBuddy -c Print "$tempPlist"
rm "$tempPlist"
I ended up with plutil as chepner suggested:
unzip -qp test.ipa Payload/*.app/Info.plist | plutil -convert xml1 -r -o - -- -

Recursive xattr fails horribly

I've been trying to figure out a way to recursively remove all of the xattr for some files, however, none of the previous methods seem to work anymore; there might be a newly introduced bug too?
$ xattr -rc .
option -r not recognized
$ xattr -c .
option -c not recognized
..and now the grand finale!
$ find . -exec xattr -l {} \;
com.apple.FinderInfo:
Traceback (most recent call last):
File "/usr/local/bin/xattr", line 11, in <module>
sys.exit(main())
File "/Library/Python/2.7/site-packages/xattr/tool.py", line 200, in main
print(_dump(attr_value))
File "/Library/Python/2.7/site-packages/xattr/tool.py", line 77, in _dump
printable = s.translate(_FILTER)
TypeError: character mapping must return integer, None or unicode
Oh look it found an xattr amongst the muck... it would be interesting to know how, what or who destroyed the xattr tool so badly. I just need to recursively remove extended attributes, really!
You appear to have a nonstandard xattr command installed in /usr/local/bin/xattr (the standard one that ships with macOS is /usr/bin/xattr). Those are Python errors, so maybe it's this one? Anyway, it doesn't use the same syntax as the standard one, so having it installed is going to cause confusion; I'd recommend either removing it or renaming it to something distinct; otherwise it's likely to break any scripts (yours or system) that try to use xattr.
This happened to me as well. and I believe is due to my $PATH
/usr/local/bin:/usr/bin
My user local bin comes before my system usr/bin.
Thanks to these posts I figured out the problem.
xattr was installed in two locations.
Show whether the target is a builtin, a function, an alias or an external executable.(Source) /
type -a xattr
# xattr is /usr/local/bin/xattr
# xattr is /usr/bin/xattr
and they are different for sure.
/usr/local/bin/xattr -h
usage: xattr [-slz] file [file ...]
xattr -p [-slz] attr_name file [file ...]
xattr -w [-sz] attr_name attr_value file [file ...]
xattr -d [-s] attr_name file [file ...]
The first form lists the names of all xattrs on the given file(s).
The second form (-p) prints the value of the xattr attr_name.
The third form (-w) sets the value of the xattr attr_name to attr_value.
The fourth form (-d) deletes the xattr attr_name.
options:
-h: print this help
-s: act on symbolic links themselves rather than their targets
-l: print long format (attr_name: attr_value)
-z: compress or decompress (if compressed) attribute value in zip format
VS.
/usr/bin/xattr -h
usage: xattr [-l] [-r] [-s] [-v] [-x] file [file ...]
xattr -p [-l] [-r] [-s] [-v] [-x] attr_name file [file ...]
xattr -w [-r] [-s] [-x] attr_name attr_value file [file ...]
xattr -d [-r] [-s] attr_name file [file ...]
xattr -c [-r] [-s] file [file ...]
The first form lists the names of all xattrs on the given file(s).
The second form (-p) prints the value of the xattr attr_name.
The third form (-w) sets the value of the xattr attr_name to the string attr_value.
The fourth form (-d) deletes the xattr attr_name.
The fifth form (-c) deletes (clears) all xattrs.
options:
-h: print this help
-l: print long format (attr_name: attr_value and hex output has offsets and
ascii representation)
-r: act recursively
-s: act on the symbolic link itself rather than what the link points to
-v: also print filename (automatic with -r and with multiple files)
-x: attr_value is represented as a hex string for input and output
So, if you do want to keep both for whatever reason, then you can just call them explicitly like so:
/usr/bin/xattr -lr ~
/usr/local/bin/xattr -l ~

zip warning: 'name not matched' inside bash loop for

I'm trying to build a plugin which has the following base script inside its makefile:
$(ZIP_FILE):
git archive --format zip --prefix $(NAME)/ --output $(ZIP_FILE) HEAD
mkdir -p $(NAME)/resources/bin
ln -s `pwd`/addon.xml $(NAME)
zip -9 -r -g $(ZIP_FILE) $(NAME)/addon.xml
for arch in $(ARCHS); do \
ln -s `pwd`/resources/bin/$$arch $(NAME)/resources/bin/$$arch; \
zip -9 -r -g $(ZIP_FILE) $(NAME)/resources/bin/$$arch; \
done
Yet, I can't figure out why this error pops up every time:
zip warning: name not matched: plugin.video.pulsar/resources/bin/windows_x86
And repeats for each arch....??
P.S. this is what it looks like inside terminal:
git archive --format zip --prefix plugin.video.pulsar/ --output plugin.video.pulsar-0.4.6.zip HEAD
mkdir -p plugin.video.pulsar/resources/bin
ln -s `pwd`/addon.xml plugin.video.pulsar
zip -9 -r -g plugin.video.pulsar-0.4.6.zip plugin.video.pulsar/addon.xml
updating: plugin.video.pulsar/addon.xml (deflated 59%)
for arch in windows_x86 darwin_x64 linux_x86 linux_x64 linux_arm; do \
ln -s `pwd`/resources/bin/$arch plugin.video.pulsar/resources/bin/$arch; \
zip -9 -r -g plugin.video.pulsar-0.4.6.zip plugin.video.pulsar/resources/bin/$arch; \
done
zip warning: name not matched: plugin.video.pulsar/resources/bin/windows_x86
zip error: Nothing to do! (try: zip -9 -r -g plugin.video.pulsar-0.4.6.zip . -i plugin.video.pulsar/resources/bin/windows_x86)
zip warning: name not matched: plugin.video.pulsar/resources/bin/darwin_x64
It's because that file (plugin.video.pulsar/resources/bin/windows_x86) really does not exist.

How do I remove the "extended attributes" on a file in Mac OS X?

I have an AppleScript script that runs a stress test. Part of the test is to open, save, and close certain files. Somehow, the files have picked up some "extended attributes" that prohibit the files from being saved. That causes the stress test to fail.
How do I remove the extended attributes?
Use the xattr command. You can inspect the extended attributes:
$ xattr s.7z
com.apple.metadata:kMDItemWhereFroms
com.apple.quarantine
and use the -d option to delete one extended attribute:
$ xattr -d com.apple.quarantine s.7z
$ xattr s.7z
com.apple.metadata:kMDItemWhereFroms
you can also use the -c option to remove all extended attributes:
$ xattr -c s.7z
$ xattr s.7z
xattr -h will show you the command line options, and xattr has a man page.
Removing a Single Attribute on a Single File
See Bavarious's answer.
To Remove All Extended Attributes On a Single File
Use xattr with the -c flag to "clear" the attributes:
xattr -c yourfile.txt
To Remove All Extended Attributes On Many Files
To recursively remove extended attributes on all files in a directory, combine the -c "clear" flag with the -r recursive flag:
xattr -rc /path/to/directory
A Tip for Mac OS X Users
Have a long path with spaces or special characters?
Open Terminal.app and start typing xattr -rc, include a trailing space, and then then drag the file or folder to the Terminal.app window and it will automatically add the full path with proper escaping.
Try using:
xattr -rd com.apple.quarantine directoryname
This takes care of recursively removing the pesky attribute everywhere.
Answer (Individual Files)
1. Showcase keys to use in selection.
xattr ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
# com.apple.FinderInfo
# com.apple.lastuseddate#PS
# com.apple.metadata:kMDItemIsScreenCapture
# com.apple.metadata:kMDItemScreenCaptureGlobalRect
# com.apple.metadata:kMDItemScreenCaptureType
2. Pick a Key to delete.
xattr -d com.apple.lastuseddate#PS ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
xattr -d kMDItemIsScreenCapture ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
3. Showcase keys again to see they have been removed.
xattr -l ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
# com.apple.FinderInfo
# com.apple.metadata:kMDItemScreenCaptureGlobalRect
# com.apple.metadata:kMDItemScreenCaptureType
4. Lastly, REMOVE ALL keys for a particular file
xattr -c ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
Answer (All Files In A Directory)
1. Showcase keys to use in selection.
xattr -r ~/Desktop
2. Remove a Specific Key for EVERY FILE in a directory
xattr -rd com.apple.FinderInfo ~/Desktop
3. Remove ALL keys on EVERY FILE in a directory
xattr -rc ~/Desktop
WARN: Once you delete these you DON'T get them back!
FAULT ERROR: There is NO UNDO.
Errors
I wanted to address the error's people are getting.
Because the errors drove me nuts too...
On a mac if you install xattr in python, then your environment may have an issue.
There are two different paths on my mac for xattr
type -a xattr
# xattr is /usr/local/bin/xattr # PYTHON Installed Version
# xattr is /usr/bin/xattr # Mac OSX Installed Version
So in one of the example's where -c will not work in xargs is because in bash you default to the non-python version.
Works with -c
/usr/bin/xattr -c
Does NOT Work with -c
/usr/local/bin/xattr -c
# option -c not recognized
My Shell/Terminal defaults to /usr/local/bin/xattr because my $PATH
/usr/local/bin: is before /usr/bin: which I believe is the default.
I can prove this because, if you try to uninstall the python xattr you will see:
pip3 uninstall xattr
Uninstalling xattr-0.9.6:
Would remove:
/usr/local/bin/xattr
/usr/local/lib/python3.7/site-packages/xattr-0.9.6.dist-info/*
/usr/local/lib/python3.7/site-packages/xattr/*
Proceed (y/n)?
Workarounds
To Fix option -c not recognized Errors.
Uninstall any Python xattr you may have: pip3 uninstall xattr
Close all Terminal windows & quit Terminal
Reopen a new Terminal window.
ReRun xattr command and it should now work.
OR
If you want to keep the Python xattr then use
/usr/bin/xattr
for any Shell commands in Terminal
Example:
Python's version of xattr doesn't handle images at all:
Good-Mac:~ JayRizzo$ xattr ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
# com.apple.FinderInfo
# Traceback (most recent call last):
# File "/usr/local/bin/xattr", line 8, in <module>
# sys.exit(main())
# File "/usr/local/lib/python3.7/site-packages/xattr/tool.py", line 196, in main
# attr_value = attr_value.decode('utf-8')
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb0 in position 2: invalid start byte
Good-Mac:~ JayRizzo$ /usr/bin/xattr ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
# com.apple.FinderInfo
# com.apple.lastuseddate#PS
# com.apple.metadata:kMDItemIsScreenCapture
# com.apple.metadata:kMDItemScreenCaptureGlobalRect
# com.apple.metadata:kMDItemScreenCaptureType
Man Pages
MAN PAGE for OSX xattr
MAN PAGE for Python xattr VERSION 0.6.4
NOTE: I could not find the python help page for current VERSION 0.9.6
Thanks for Reading!
Another recursive approach:
# change directory to target folder:
cd /Volumes/path/to/folder
# find all things of type "f" (file),
# then pipe "|" each result as an argument (xargs -0)
# to the "xattr -c" command:
find . -type f -print0 | xargs -0 xattr -c
# Sometimes you may have to use a star * instead of the dot.
# The dot just means "here" (whereever your cd'd to
find * -type f -print0 | xargs -0 xattr -c

Resources