I have a find expression looking for node_modules directories. Some of the results are node_modules directories within a parent node_modules directory.
I'm only interested in finding the top most node_modules directory and performing an action on it, i.e. add a .metadata_never_index file so that Spotlight (macOS) doesn't index it.
I'm struggling to find a solution which deals with this; can find do this for me, or do I need to calculate it manually (maybe through string manipulations)?
As a bonus, I'd like to ignore all folders which already contain the .metadata_never_index file, if possible.
EDIT: Some context; this will run as a cron job and periodically look for node_modules in my ~/Sites directory, i.e multiple top-level projects.
After a bit more searching, I found a solution on SuperUser.
To summarise Paxali's answer:
find /home/code -type d -name ".git" | grep -v '\.git/'
In english: find me all directories named ".git" and filter out any occurences in the resultlist which contain ".git/" (dot git slash).
Except in my case, I used node_modules/ instead of .git/.
My working code:
find -f ~/Sites . -name node_modules | grep -v 'node_modules/' | while read fname; do
touch $fname/.metadata_never_index
done
Find the top most modules can be found by using
npm command with flag --depth
npm list --depth=0
you can also create aliases as follows:
alias ng="npm list -g --depth=0 2>/dev/null"
alias nl="npm list --depth=0 2>/dev/null"
Related
I'm not allowed to use rsync on the cluster I'm working on so I need to use cp. I want to copy a large directory including all files and subfolders etc. but without any folders that have the name "outdir".
I tried cp -r -v ./!(outdir) ../target-directory/
but it still copies all folders and contents in deeper directories with the name outdir. It only included the outdir folders in the highest directory.
I also tried cp -r ./*/!(outdir) ../target-directory/ but that one copied all files into the folder without keeping any hirarchy or folders etc.
I also tried certain find commands but it didn't work, but maybe I was just doing something stupid. I'm a beginner with bash so if you could explain your answer and what the flags etc. do that would really be helpfull, I've been trying forever now, on what I think shouldn't be that hard to do.
Instead of cp, you can use tar with option --exclude to control what you want copied or not.
The full command is:
tar --exclude="outdir" -cvpf - . | (cd TARGET_DIRECTORY; tar -xpf -)
So any path that contains the "outdir" pattern will be excluded.
Without the --exclude option, it will copy the entire structure of your current directory under TARGET_DIRECTORY.
You can replace the . in the first tar by your desired source directory.
I am not familiar with osx terminal command.
I have a java project containing many package.
Some classes have same name in different package.
I need to copy all of the class files into a directory, so I need to add
corresponding package prefix on each files.
For example, I have root/com/example1/test.java and root/com/example2/test.java two classes having the same name in different packages. I need to copy them into root directory and add prefix, making them become example1.test.java and example2.test.java in root directory.
How to do this using terminal command?
This solution is not perfect but it should do what you want (assuming I understood your question correctly):
Create a file doCopy.sh with the following content:
#!/bin/bash
origName=$1
newName=$(echo $origName | sed -e 's|/|.|g')
echo cp $origName $newName
Then make it executable and call it for each of your files:
chmod +x doCopy.sh
find root -type f -exec ./doCopy.sh {} \;
Please verify the commands that will be printed. If you are satisfied you can remove the echo from doCopy.sh and rerun the find to actually copy the files.
I need a script that will find and get me all files in all subdirectories (and leave them in the folder structure as they are now). I know how to find and print that files:
find . -name "something.extension"
The point is, in those directories are lots files that was used before, but I don't want to get those, so the script should only find me files that matches some kind of path pattern which is:
xxx/trunk/xxx/src/main/resources
xxx is different everytime, and after resources there are still some folders that directories are different based on xxx.
Every top xxx folder contains folder named 'tags' (the same level as trunk) that stores previous releases of module (and every release has files that name I am looking for, but I don't want outdated files).
So I want to find all that files in subdirectories of that path pattern that I specified and copy to new location but leave folder structure as it is right now.
I am using Windows and cygwin.
Update
I combined answer commands that 'that other guy' posted below, and it works. Just to be clear I have something like this:
find */trunk/*/src/main/resources -name "something.extension" -exec mkdir -p /absolute/target/path/{} \; -exec cp {} /absolute/target/path/{} \;
Thanks.
Instead of searching under the entire current directory (.), just search under the directories you care about:
find */trunk/*/src/main/resources -name "something.extension"
I currently have a set of folders that I need to duplicate the structure into another folder.
I currently work with photos that are dumped into a Dump folder in groups.
Eg.
Photo Dump
Group1
Group2 etc
I would like to have a script to recreate these folders without the files to the good folder so that I don't have to recreate them manually
Any ideas?
Nathan
If I understand correctly, you want to copy the parent folder and all of its subfolders, but none of the files contained therein. There might be a simpler way, but I just threw together this Terminal command (which should also work on Linux or anywhere else with Bash):
ls -R | grep :$ | sed 's/\.\/\(.*\):$/\1/' | \
while read thisFolder; do mkdir -p "destination"/"$thisFolder"; done
It will copy the folder structure of all folders in the current directory into a folder called "destination"; you can of course change this to any path you wish, e.g. ~/Desktop/"Folder Copies" or whatever.
Take care to first "cd" into whatever directory contains the folder tree you want to duplicate, because if you run it as soon as you open the terminal, you'll wind up with a replication of your entire home folder directory structure, including the many contained within Library.
I found this to be a tad clearer:
find 'Photo Dump' -type d | sed -e 's:^Photo Dump:destination:g' | sort | xargs mkdir
find 'Photo Dump' -type d -> List all folders in "Photo Dump"
sed -e 's:^Photo Dump:destination:g' - Since all folders listed in the above step will start with Photo Dump/..., we can just replace the beginning with the folder we want to copy the structure to (in this case I called it destination)
sort - Sorts results. This is required so that the parent folders are created before the children
xargs mkdir - Passes all the results from above into mkdir so it can create the folders
I am using Mercurial under Linux. I would like to exclude all files containing the pattern *.pro.user* from the version control system.
I tried to list all the files with:
find . -name "*.pro.user*"
This turned out also some results which are in the .hg folder:
...
./.hg/store/data/_test_run_multiple/_test_run_multiple.pro.user.i
./.hg/store/data/_test_non_dominated_sorting/_test_sorting.pro.user.i
./Analyzer/AlgorithmAnalyzer.pro.user
./Analyzer/AlgorithmAnalyzer.pro.user.a6874dd
...
I then tried to pipe this result to the hg forget command like:
find . -name "*.pro.user*" | hg forget
but I get:
abort: no files specified
My guess is that the list needs to be processed in some way in order to be passed to hg forget.
I would like to ask:
How can I pass the result of my find query into the hg forget command?
Since the query result contains files in the "private" folder .hg, is it a good idea? I hope that Mercurial will ignore that request, but shoud I remove those results somehow?
Try the following:
hg forget "set:**.pro.user*"
This tells Mercurial to forget any files that match the fileset **.pro.user*. As the fileset is defined in Mercurial, it won't go into the .hg directory. You can do even more with filesets by looking at: hg -v help filesets
The ** at the start means to work in subdirectories, rather than just the current directory.
First of all, you can use find * -name "*.pro.user*" to avoid looking in .hg.
Mercurial's forget command requires its arguments on the command line. So you need to use xargs:
find * -name "*.pro.user*" | xargs hg forget
Alternatively you can ask find to do the job:
find * -name "*.pro.user*" -exec hg forget {} \;
Finally, you should add *.pro.user* to your .hgignore file.