I am trying to automatically display an image in the terminal whenever a file is updated or added to a directory. I can manually do this with imgcat in iTerm2, and I can get fswatch to report correctly when a file is changed. But I can't get them to play together. I thought this would work but it reports xargs: imgcat: No such file or directory
fswatch *.png | xargs -n1 -I{} imgcat
Related
I have a script in ~/bin called go_refresh. It's definitely there. I run fswatch like so:
fswatch -o /usr/local/var/www/wp_sites/test/wp-content/themes/test/style.css | xargs -n1 -I{} ~/bin/go_refresh
When I change the file, I get this error once:
xargs: /Users/my_dir/bin/go_refresh: No such file or directory
And the script doesn't run.
I have files with extension .mp3 that are in different folders within a directory, and I need to move them all to one directory to work with. I have looked at multiple tutorials and questions on SO, and no matter what I try, I either get
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
or "No such file or directory".
There are way too many to into each individual folder, but for now I cd into one of the folders. With this:
mv *.mp3 /Users/myname/Volumes/LaCie/model/folder/media
I get the "usage" error above. I looked at Moving files to a directory and tried:
find . | grep ".mp3" | xargs mv /Users/myname/Volumes/LaCie/model/folder/media
and get same error.
What am I doing wrong? What is the correct syntax? Also, will I be able to extract the mp3 files and move them if I'm in a directory that contains the directory with the files, but not in that directory itself? I appreciate insights into this. Thanks.
EDIT: A major part of this issue was that the path when using /Volumes starts with /Volumes. I was doing /Users/myname/Volumes and that was one reason I had so much trouble.
The problem with the way you're using xargs is that by default, xargs will append the arguments to the end of the command string you've provided it. So you'll end up running a bunch of mv commands that look like this:
mv /Users/myname/Volumes/LaCie/model/folder/media foo.mp3
You can fix that by telling xargs where to place the arguments within the command:
<other commands> | xargs -I{} mv {} /Users/myname/Volumes/LaCie/model/folder/media
The -I option lets you provide any arbitrary string as a placeholder for where the args should go. I used {} just because that seems to be the conventional token that you see used in similar contexts (such as with the -exec option of find, as shown below).
But there's an easier way to do it, using the find command's -exec option:
find . -name '*.mp3' -exec mv {} /Users/myname/Volumes/LaCie/model/folder/media \;
Also note the -name '*.mp3' part, which lets you get rid of the | grep ".mp3" part.
Lastly, just to be safe, I'd personally put a / at the end of your destination path. If the media directory doesn't exist in /Users/myname/Volumes/LaCie/model/folder, or if a non-directory item (such as a regular file or a symlink) named media exists in that location, then the find command above will happily just move all your mp3 files, one at a time, to that folder, creating a file named media there each time. And you will have lost all of your mp3 files except for the last one, which will now be a file named media.
However, with a trailing /, if media is not a directory, the mv commands will fail with an error saying so. So the revised command would be:
find . -name '*.mp3' -exec mv {} /Users/myname/Volumes/LaCie/model/folder/media/ \;
Update: Per Gordon Davisson's comment below, you should also consider adding -i or -n to the mv command, to avoid accidentally overwriting files with duplicate names. For example, if you have a/foo.mp3 and b/foo.mp3, the above command will overwrite one with the other. The -i option will cause mv to prompt you to confirm each file move, whereas the -n option (a.k.a. --no-clobber) will prevent mv from overwriting a file if a file with the same name already exists.
There are different implementations and versions of mv. You can check the allowed syntax of your version using man mv.
If you have GNU mv you could use mv -t target/dir *.mp3.
Most implementations should support mv *.mp3 target/dir.
If your mv only supports the absolute minimum of mv source target with exactly one source and one target file you can use the following command which should always work if target/dir/ exists.
for i in *.mp3; do mv "$i" "target/dir/$i"; done
I am trying to reorganise images based on the species that is within an image. Among other information, the species name can be found in the IPTC metadata (see link to the Inspector image). I am attempting to do this in bash on macOS and have tried following code (with template species name and directory):
find . -iname "*.jpg" -print0 | xargs -0 grep -l "Species Name" | xargs -0 -I {} mv {} ~/example/directory
I have also tried using the exiftool package, where the relevant information is in the Subject tag:
find . -iname "*.jpg" -print0 | xargs -0 exiftool -Subject | grep "Species Name" | xargs -0 -I {} mv {} ~/example/directory
However, I receive following error message, which I assume to be a result of a misuse of grep or the last xargs:
mv: rename (standard input)
to ~/example/directory(standard input)
: No such file or directory
Any ideas what could fix this issue? Thank you in advance.
Exiftool can move and rename files based upon the file metadata and is much faster calling it once for an entire directory than calling it individually for each file in a loop (Common Mistake #3).
I believe you could use this command to do your sorting:
exiftool -if '$subject=~/Species Name/i' -directory=~/example/directory .
Breakdown:
-if '$subject=~/Species Name/i' Does a regex comparison of the Subject tag for the "Species Name". I added the i at the end to do the comparison case insensitively, modify as desired.
-directory=~/example/directory If the -if condition is met, then the file will be moved to the stated directory.
Looks like grep's output newline is interfering there, as you're using a clean -0 pipeline, you should do so with grep -- in Linux it would be grep -Z ... (or --null), dunno if Mac OS's has a similar one.
I've got a bunch of subdirectories with a couple thousand PNG files that will be sent through Photoshop, creating PSD files. Photoshop can only output those to a single folder, and I want to move each one back to their original directory - so the new file foo_bar_0005.psd should go to where foo_bar_0005.png already is. Every filename only exists once.
Can somebody help me with this? I'm on OSX.
You might start from this minimal script:
#!/bin/bash
search_dir="search/png/from/this/directory/"
psd_dir="path/to/psd/directory/"
for psd_file in "$psd_dir"*.psd; do
file_name="$(echo $psd_file | sed 's/.*\/\(.*\).psd$/\1/g')"
png_dir="$(find $search_dir -name $file_name.png | grep -e '.*/' -o)"
mv $psd_file $png_dir
done
But note that this script doesn't include any error handlers e.g. file collision issue, file not found issue, etc.
Each file found with this find is piped to a Bash command that successively make the psd conversion and move the .psd to the .png original directory.
psd_dir=/psd_dir/
export psd_dir
find . -type f -name '*.png' | xargs -L 1 bash -c 'n=${1##*/}; echo photoshop "$1" && echo mv ${psd_dir}${n%.png}.psd ${1%/*}/; echo' \;
The echo are here to give you an overview of the result.
You should remove them to launch the real photoshop command.
Is there a way to use command line to search all subfolders with a folder (unlimited depth) to find and automatically open every file that's named footer.php ?
I was able run
find /desktop/themes -name footer.php
and it found all of the files but I don't know how to make it open all of them automatically. Does anyone know how to do this?
(I'm running this in cygwin in case that helps.)
Try using gvim -p. That will open all files in different tabs:
find /desktop/themes -name footer.php -print0 | xargs -0 gvim -p
Note the use of -print0 with xargs -0 for safe parsing of find's output.