I need to make an update of a project on my webserver. Unfortunately others have already changed some of the files on the server, which I don't want to overwrite. I can securely overwrite all files that begin with "Builder" (like "BuilderUser.php" or "BuilderTemplate.php").
My idea was to copy my local directory and remove all files that don't begin with "Builder" and then upload the resulting folder. And I'm using OS X. Is there any way to remove all files that do not prefixed with "Builder"?
Open a terminal, navigate to the root of your project, and type
find . -type f | grep -v '/Builder[^/]*' | xargs rm
find will print anything in . or subdirectories, of -type f meaning regular files (as opposed to block devices, symlinks, directories, etc.). grep will print any line that (because of -v) doesn't match the pattern. For the pattern, / indicates a directory, 'Builder' must be the first thing that appears after the directory (so in the filename), [^/] means any character except a / (directory separator), and * means any number of the last item (non-slashes). xargs then takes files from the pipe and passes them as arguments to rm.
Note that this will only work on files without spaces in the name. If you need one that handles spaces, post or look up zero-delimiting options in the man pages.
Related
Ok so i did something very stupid (copying a file and renaming it '.') since I thought it would just copy it as .uniprot_sprot.fasta.gz.icloud.
cp /path/.uniprot_sprot.fasta.gz.icloud .
and now I don't know how to remove it from current directory as it would be removing '.' itself.
What can I do?
This doesn't work. It says: No such file or directory
rm .uniprot_sprot.fasta.gz.icloud
On the other hand:
ls -a
gives this:
.
..
uniprot_sprot.fasta.gz.icloud
You have not copied a file and renamed it . (at any rate if you're running a sane *nix). Instead you have copied the file to the current directory with the name of the original file. (If you pass a directory to cp as the destination, files will be placed in that directory. . is the current directory, so this is all that has happened.) If you want to remove it you can just rm uniprot_sprot.fasta.gx.iscloud or explicitly rm ./uniprot_sprot.fasta.gx.iscloud. What you have tried to do is to remove a file whose name starts with ., which is a different thing.
Edit: I was unaware when I wrote this, but this is in fact simply down to . existing as a real, regular hardlink. At syscall level you can create a file whose name contains anything except / and \x00 (yep, including \n), assuming your filesystem allows it. However, the links . and .. are already present and thus unavailable as a file name. #thatotherguy links to the kernel source for the rmdir syscall, showing that in modern Linux at least it is the kernel itself which ultimately prevents you from deleting . and ...
Note that in bash, . at the beginning of a line by itself means source.
See this question on unix.se and its linked dupe for more information on the filename problem.
-- CONTEXT and what's working so far --
I use this command in OSx Terminal to get a csv file with all filenames structured according to their paths, inside a folder:
find 'folder' -type f -print | sed 's_/_,_g' > ~/filelist.csv
Other info:
Folder name - doesn't contain "duc" for sure
Subfolders
a) Subfolders may or may not contain "duc" string in their name (as for now they don't but I can't be sure if it will happen or not in the future)
b) All subfolders may or may not contain files that contain the string in their names
-- WHAT I WOULD LIKE --
That the filelist.csv would list/have filenames that contain a string in their name: "duc" and its variations - duc, DUC, DuC... (e.g. "12345 duc.pdf", "12345 DUC2.pdf")
The list should also show filepaths
It should be taken into consideration that these files may or may not be inside a subfolder with the string in its filename
Can anyone give me a hand?
Thank you in advance
I'm looking for a script to change an existing folder structure quickly on my synology nas using ssh from YYYY/MM/DD/ to YYYY-MM-DD/ so nested to flat but struggling to find one or any examples probably due to me not searching for the correct terminology.
I did start to use exiftool and go through moving each item but the collection is taking ages.
for example an image01 that currently resides in say 2020/01/01/images01.jpg needs to move to 2020-01-01/images.jpg
image and video files only currently live in the day folders.
For example, you can do this with this command:
find . -mindepth 3 -type d |awk -F"/" 'system("mv " $2"/"$3"/"$4" "$2"-"$3"-"$4" && rmdir "$2"/"$3" && rmdir "$2" 2>/dev/null")'
Example input folder structure:
./2020/06/12/img1.jpg
./2020/06/12/file2.mpg
./2020/05/10/img2.jpg
./2020/05/10/img1.jpg
Result:
./2020-05-10/img1.jpg
./2020-05-10/img2.jpg
./2020-06-12/img1.jpg
./2020-06-12/file2.mpg
Explanation:
find . searches in the current directory
-mindepth 3 only searches at level 3 nesting
-type d only search for directories
| creates a pipe, directing the find result to AWK
-F"/" sets the AWK field separator to /
system command is executed for each line which transfers files to the new directory and deletes unnecessary old directories
&& do next command only when previous ones were successful
2>/dev/null directs stderr to the void so that you won't see any errors trying to delete a non-empty "year" directory
You cannot use rm -rf because the year directory may still contain other directories, hence using rmdir twice.
You can resolve the stderr redirection more elegantly by testing whether the directory of the year is empty before deleting it,
I do not put this test so as not to obscure the idea of action unnecessarily.
First, my problem:
I have thousands of test files that currently call a function inside of another function. This could be placed anywhere in the file but can only be called once. The structure is as follows:
md = mod.solver(mod,TestFunctionCall());
I need to replace the function call TestFunctionCall() with a string, specifically, I need to remove Call() and replace it with a ' character. I also need to put a ' mark at the beginning of TestFunctionCall(). So essentially I want to do the following:
TestFunctionCall() -> 'TestFunction'
So my final output should look like this:
md = mod.solver(mod,'TestFunction');
The problem is, I have many different names for TestFunction and although they end in Call(), they might have different names (ie. MySolverCall(), HelloWorldCall(), etc.).
Since all the files I want have the name and extension test*.txt, I figured this would be easy enough for find and sed. So I used the following command:
find . -type f -name "test*.txt" -exec sed "s/solver(mod,\(.*\)Call()/solver(md,\'\1\'/g" {} \;
This spits out a ton of text at me with the files I'm editing, and then it does correctly replace FunctionNameCall() with 'FunctionName', however it only does so in about 10 files before deciding to stop. It seems no matter how many different files I call this command on, it will only edit around 10 files before stopping.
How can I make it edit every file with the name test*.txt in the current directory?
I was wondering how to move a number of folders to another one, according to the filename of a file inside each of the folders.
I mean, let's assume I have a big amount of folders, each one with a name starting by 'folder*', each one containing 3 files. Specifically one the files contains a string which might be '-100', '-200' or '-300' for example.
I want to move the folders containing the files according to this strings, and put them in a folder called 'string'. For example, to put every folder containing a file which contains the string '-100' into the folder 'FOLDER1'I'm trying something like:
find folder* -name '100' -exec mv {} folder* FOLDER1
but it returns -bash: /usr/bin/find: Argument list too long.
How can I pass less arguments to find at every step so I don't get this.
Thank in advance.
Best.
Using your example, and running in the topmost folder containing all the folders, I believe that what you need is this:
grep -rlw folder* -e "-100" | xargs -I % mv % FOLDER1