How do I move files by looking at part of a file name - linux

My web application creates multiple image thumbnail files when users upload images.
I want to separate original images and thumbnail images. Thumbnail images contain 'crop-smart' in their file name.
For example, original image is watermelon.jpg, then thumbnail's name is watermelon_jpg_120x120_crop-smart.jpg.
How do I find by say 'crop-smart' and either move them to the different folder or delete them?

Standard file globbing will do this, the exact details may vary depending out which shell you are running but for your exact problem, it should be the same:
mv -- *_crop-smart.jpg /path/to/new/folder/
(This will also work if you have spaces in the filename)
Note the -- signals to mv that no more option switches will follow, so even if filenames look like options, mv won't get confused.

Related

Unix create multiple files with same name in a directory

I am looking for some kind of logic in linux where I can place files with same name in a directory or file system.
For e.g. i create a file abc.txt, so the next time if any process creates abc.txt it should automatically check and make the file named as abc.txt.1 should be created, then next time abc.txt.2 and so on...
Is there a way to achieve this.
Any logic or third party tools are also welcomed.
You ask,
For e.g. i create a file abc.txt, so the next time if any process
creates abc.txt it should automatically check and make the file named
as abc.txt.1 should be created
(emphasis added). To obtain such an effect automatically, for every process, without explicit provision by processes, it would have to be implemented as a feature of the filesystem containing the files. Such filesystems are called versioning filesystems, though typically the details are slightly different from what you describe. Most importantly, however, although such filesystems exist for Linux, none of them are mainstream. To the best of my knowledge, none of the major Linux distributions even offers one as a distribution-supported option.
Although it's a bit dated, see also Linux file versioning?
You might be able to approximate that for many programs via a customized version of the C standard library, but that's not foolproof, and you should not expect it to have universal effect.
It would be an altogether different matter for an individual process to be coded for such behavior. It would need to check for existing files and choose an appropriate name when opening each new file. In doing so, some care needs to be taken to avoid related race conditions, but it can be done. Details would depend on the language in which you are writing.
You can use BASH expression to achieve this. For example if I wanted to make 10 files all with the same name, but having a unique number value I would do the following:
# touch my_file{01..10}.txt
This would create 10 files starting at 01 all the way to 10. This method is also hand for looping over files in a sequence or if your also creating directories.
Now if i am reading you question right your asking that if you move a file or create a file in a directory. you would want the a script to automatically create a new file for you? If that is the case then just use a test and if there is a file move that file and mark it. Me personally I use time stamps to do so.
Logic:
# The [ -f ] tests if the file is present
if [ -f $MY_FILE_NAME ]; then
# If the file is present move the file and give it the PID
# That way the name will always be unique
mv $MY_FILE_NAME $MY_FILE_NAME_$$
mv $MY_NEW_FILE .
else
# Move or make the file here
mv $MY_NEW_FILE .
fi
As you can see the logic is very simple. Hope this helps.
Cheers
I don't know about Your particular use case, but You may try to look at logrotate:
https://wiki.archlinux.org/index.php/Logrotate

pycharm jetbrains to search for text NOT in test*.py filename pattern

In Pycharm, when search for files that contain a given text e.g. hitting Ctrl-Shift-F, we have the File mask box as in below snapshot to filter file name pattern.
I want a NOT filter here e.g. search for files not starting with test*.py. How can we archive this?
Note
Although this question is old, I'll leave the answer here just in case someone else reaches the question.
Solution
The way to exclude results in File mask is by adding a ! before the mask, for example: !*test*.py
However, this might generate an unwanted situation, because it can bring results from configuration files, or temporary files, or any file we don't want. For this, the solution is to have multiple masks at once, and this can be achieved by separating masks with , (comma).
Example
If we want all files containing the word def in .py files, excluding files containing the word tests for any type of file, and models ending in .py, we would use the File mask: !*test*, !*models*.py, *.py
Hope this helps!

os.symlink and window's .lnk files are different

I am processing a big images dataset and I'm trying to reorder the files in classes, while at the same time keeping the original directory structure.
To do this, I make a second directory structure with symlinks to the files in the first one.
Everything works as it should but for one small detail: the symlinks created via os.symlink() do not show the image thumbnail, while if I make a link of the same file (e.g., via right click & send to Desktop) I do see the thumbnail.
I wanted to check how the two link files differ (note, the link files themselves, not the linked file), but if I try to drag the os.symlink-generated file in a text editor it opens the linked file instead (while this does not happen with the .lnk file generated via right-click).
What's the difference between the link files? Is os.symlink making something different than a .lnk file? If so, is there a way to get the thumbnail? And if there's no such way, how can I make a .lnk file instead?

How should I batch make thumbnails with the original images located in multiple subdirectories?

I have the original images in a directory structure that looks like this:
./Alabama/1.jpg
./Alabama/2.jpg
./Alabama/3.jpg
./Alaska/1.jpg
...the rest of the states...
I wanted to convert all of the original images into thumbnails so I can display them on a website. After a bit of digging / experimenting, I came up with the following Linux command:
find . -type f -iname '*.jpg' | sed -e 's/\.jpg$//' | xargs -I Y convert Y.jpg -thumbnail x100\> Y-small.jpg
It recursively finds all the jpg images in my subdirectories, removes the file type (.jpg) from them so I can rename them later, then makes them into a thumbnail and renames them with '-small' appended before the file type.
It worked for my purposes, but its a tad complicated and it isn't very robust. For example, I'm not sure how I would insert 'small-' at the beginning of the file's name (so ./Alabama/small-1.jpg).
Questions:
Is there a better, more robust way of creating thumbnails from images that are located in multiple subdirectories?
Can I make the existing command more robust (for example, but using sed to rename the outputted thumbnail before it is saved- basically modify the Y-small.jpg part).
No need to build up such a complicated construct. Make small blocks first, then connect.
I have decided to not insert -small in the middle of the filename. it makes everything more complicated. Better to use a prefix (simpler code, and also easier to derive the original filename from the thumb) which can either be a thumbsDir/ or a thumbsPrefix-.
#!/bin/sh
make_thumbnail() {
pic=$1
thumb=$(dirname "$1")/thumb-$(basename "$1")
convert "$pic" -thumbnail x100 "$thumb"
}
# Now we need a way to call make_thumbnail on each file.
# The easiest robust way is to restrict on files at level 2, and glob those
# with */*.jpg
# (we could also glob levels 2 and 3 with two globs: */*.jpg */*/*.jpg)
for pic in */*.jpg
do
make_thumbnail "$pic"
done

Linux - Restoring a file

I've written a vary basic shell script that moves a specified file into the dustbin directory. The script is as follows:
#!/bin/bash
#move items to dustbin directory
mv "$#" ~/dustbin/
echo "File moved to dustbin"
This works fine for me, any file I specify gets moved to the dustbin directory. However, what I would like to do is create a new script that will move the file in the dustbin directory back to its original directory. I know I could easily write a script that would move it back to a location specified by the user, but I would prefer to have one that would move it to its original directory.
Is this possible?
I'm using Mac OS X 10.6.4 and Terminal
You will have to store where the original file is coming from then. Maybe in a seperate file, a database, or in the files attributes (meta-data).
Create a logfile with 2 columns:
The complete filename in the dustbin
The complete original path and filename
You will need this logfile anyway - what will you do when a user deleted 2 files in different directories, but with the same name? /home/user/.wgetrc and /home/user/old/.wgetrc ?
What will you do when a user deletes a file, makes a new one with the same name, and then deletes that too? You'll need versions or timestamps or something.
You need to store the original location somewhere, either in a database or in an extended attribute of the file. A database is definitely the easiest way to do it, though an extended attribute would be more robust. Looking in ~/.Trash/ I see some, but not all files have extended attributes, so I'm not sure how Apple does it.
You need to somehow encode the source directory in the file. I think the easiest would be to change the filename in the dustbin directory. So that /home/user/music/song.mp3 becomes ~/dustbin/song.mp3|home_user_music
And when you copy it back your script needs to process the file name and construct the path beginning at |.
Another approach would be to let the filesystem be your database.
A file moved from /some/directory/somewhere/filename would be moved to ~/dustbin/some/directory/somewhere/filename and you'd do find ~/dustbin -name "$file" to find it based on its basename (from user input). Then you'd just trim "~/bustbin" from the output of find and you'd have the destination ready to use. If more than one file is returned by find, you can list the proposed files for user selection. You could use ~/dustbin/$deletiondate if you wanted to make it possible to roll back to earlier versions.
You could do a cron job that would periodically remove old files and the directories (if empty).

Resources