I want to optimize the whole test folder with jpg images from a command line.
I found this but it doesn't work:
cd /home/site/html/update/test/
find . -exec jpegtran -optimize "{}" "{}.opti.jpg" "{}" \;
I want to overwrite the existing images.
Suggestions?
Answer:
find /img/path -name "*.jpg" -type f -exec jpegtran -copy none -optimize -outfile {} {} \;
Answer:
find /img/path -name "*.jpg" -type f -exec jpegtran -copy none -optimize -outfile {} {} \;
Though it is solved here pretty earlier but talking about Python approach:
import subprocess
for image_name in arr:
subprocess.call(["jpegtran", "-your", "-instructions"])
Let's say your instruction is something like:
jpegtran -optimize -progressive -scans script_new.txt -outfile progressive.jpg original.jpg
So your instruction will be like:
subprocess.call(["jpegtran", "-optimize", "-progressive", "-scans", f"{scan_name}.txt", "-outfile", name_progressive, name_original])
For your convenience, name_progressive, name_original and scan_name are variables and concept f-string is used.
Related
i wish to rename files with single digit numbers by adding a "0" in front, while ignoring files with double digit numbers, for example: 1.fileA, 2.fileB to 01.fileA, 02.fileB, and ignoring files 10.fileK, 11.fileL
when i use the following command, nothing happens. i assume it's because find returns the full path of the filename for which my rename function does not work. below, mediaDir is the path to my folder where my media files are located.
i tried the following but it still does not work:
find "$mediaDir" -type f -name "*.mp4" -exec rename 's/^(\d)\./0$1./' {} \;
so i tried the following instead, which also does not rename the files:
find "$mediaDir" -type f -name "*.mp4" -exec rename 's/^(\d)\./0$1./' $(basename {}) \;
although the following correctly lists out the basename of the files without the fullpath
find "$mediaDir" -type f -name "*.mp4" -exec basename {} \;
i have spent a whole day googling and trying but to no avail. please help.
After struggling further to understand the find command, thanks to Kusalananda who did a great job explaining "find" that "man find" does an incomplete job of:
Basic usage of -exec
In my question above, -exec doesn't work because find returns the full path to the found file, which makes my rename's regex using ^ fail since the digit to be appended to is no more at the start of the string, being within the full path.
Using "-execdir" instead, returns only the filename minus the path; however, GNU find prefixes the returned filename with "./" which defeats my regex. the following finally worked:
find "$mediaDir" -type f -name "*.mp4" -execdir rename 's/\/(\d)\./\/0$1./' {} \;
Note that the "^" is no more in my regex expression, due to the "./" prefix that "find" appends
To use -exec instead of -execdir, the following worked:
find "$mediaDir" -type f -name "*.mp4" -exec basename {} \; -exec rename 's/\/(\d)\./\/0$1./' {} \;
It seems that "-execdir" is shorter and better than "-exec".
Use find with regex to match only one digit and then process the output in a loop, executing mv to rename the file.
while read file;
do
filename=${fil3##*/}; # Extract the directory
dir=${file%/*} # Extrasct the file name
mv "$file" "$dir/0$filename" # Execute the move command
done <<< "$(find /path/to/dir -regextype posix-extended -regex "^.*/[[:digit:]]{1}\.file.*")"
So I have a find command as below which finds the libclntsh.so.* files in a directory instantclient.
find instantclient -type f -name "*libclntsh\.so\.[0-9]*\.[0-9]*"
This results in for e.g.,
instantclient/libclntsh.so.11.1
How do I now ln within instantclient directory, ln -s libclntsh.so.11.1 libclntsh.so all with a find command in combination with exec
I should mention here that I DO NOT want to cd into instantclient.
And this is for Alpine Linux.
Use the -execdir option. As per manual:
-execdir command {} ;
Like -exec, but the specified command is run from the subdirectory containing the matched file, which is not normally the directory in which you started find. This a much more secure method for invoking commands, as it avoids race conditions during resolution of the paths to the matched files.
So your command will be:
find instantclient -type f -name "*libclntsh\.so\.[0-9]*\.[0-9]*" -execdir ln -s {} libclntsh.so \;
EDIT:
Another solution
find instantclient -type f -name "*libclntsh\.so\.[0-9]*\.[0-9]*" | xargs -I {} sh -c 'ln -s $(basename {}) instantclient/libclntsh.so'
This works for me:
$> find . -name "*.log" -exec basename '{}' \;
20160114.log
20160115.log
20160116.log
20160117.log
20160118.log
Is the {}, \ and ';' mandatory when using -exec as any other syntax simply doesn't work?
The following, more complex example doesn't work:
$> find . -name "*.log" -exec echo $(basename '{}') \;
./log/20160114.log
./log/20160115.log
./log/20160116.log
./log/20160117.log
./log/20160118.log
echo here is just to demonstrate. I eventually plan to use something like rm $TARGET_DIR/$(basename '{}') in its placeā¦ It just doesn't work that way (nesting). Any ideas?
So I have a directory called testdir and I want to delete the underscores in the filenames from the files in that directory.
I tried to use this command
find testdir -type f -exec ls {} \; | sed 's/_*//'
It will output the filenames without the underscores but it won't delete the underscores permanently. Could anyone help me?
Thanks!
If you are just looping through the files in your dir, use a simple loop:
while IFS= read -r file
do
echo mv "$file" "${file//_/}" #once you are sure it works, remove the echo!
done < <(find -type f -name "*_*")
This will feed the while loop with the output of the find command. Then, uses ${var//_/} to remove all _ in the name.
Why wasn't your approach working?
Because you are saying
find ... -exec ls {} \; | sed '...'
That is, you are finding something and then changing the output with sed. That is, nothing is done to the file itself.
This may help you
find testdir -type f | rename 's/_//'
Regards
I need to search all duplicated files in folder and subdirectories of this folder. how use find and md5 to get list for all files?
find ./ -type f -name '*' -exec md5sum {} > checksums.txt \;
above comand doesnt work
or is it possible to remove the 'newer one'?
thx in advance
You overwrite the checksums.txt during the find with each file found.
The -name '*'does not add anything to the query, so you could enter
find . -type f -exec md5sum {} \; > checksums.txt
Or use append (>>).