linux commands to search a given folder - linux

I have a folder in ~/Downloads with lots of
files and folders scattered. This consists of various files of different
extensions. I need to copy only the
.pdf files within various directories to ~/pdfs

Use find:
find ~/Downloads -type f -name "*.pdf" -exec cp {} ~/pdfs \;

if ~/pdfs exists in your system use the following command
cd ~/Downloads ; cp -r *.pdf ~/pdfs
if ~/pdfs does not exists in your system use the following command
cd ~/Downloads ; mkdir ~/pdfs ; cp -r *.pdf ~/pdfs

In order to deal with potential file names with spaces, etc., I would recommend this approach:
find ~/Downloads/. -type f -name "*.pdf" -print0 | xargs -0 -I_ cp _ ~/pdfs/.

Related

Find all files and unzip specific file to local folder

find -name archive.zip -exec unzip {} file.txt \;
This command finds all files named archive.zip and unzips file.txt to the folder that I execute the command from, is there a way to unzip the file to the same folder where the .zip file was found? I would like file.txt to be unzipped to folder1.
folder1\archive.zip
folder2\archive.zip
I realize $dirname is available in a script but I'm looking for a one line command if possible.
#iheartcpp - I successfully ran three alternatives using the same base command...
find . -iname "*.zip"
... which is used to provide the list of / to be passed as an argument to the next command.
Alternative 1: find with -exec + Shell Script (unzips.sh)
File unzips.sh:
#!/bin/sh
# This will unzip the zip files in the same directory as the zip are
for f in "$#" ; do
unzip -o -d `dirname $f` $f
done
Use this alternative like this:
find . -iname '*.zip' -exec ./unzips.sh {} \;
Alternative 2: find with | xargs _ Shell Script (unzips)
Same unzips.sh file.
Use this alternative like this:
find . -iname '*.zip' | xargs ./unzips.sh
Alternative 3: all commands in the same line (no .sh files)
Use this alternative like this:
find . -iname '*.zip' | xargs sh -c 'for f in $#; do unzip -o -d `dirname $f` $f; done;'
Of course, there are other alternatives but hope that the above ones can help.

how to find and copy files in a sub directory from parent directory linux

I have several parent folders like GJ1, GJ2 etc. Each of these folders contain three images like GJ11_F.jpg, GJ11_P.jpg. I need to only display all the GJ11_F.jpg files including their respective parent directories.
find . -type f -name "*_F.jpg" | xargs cp -t ~/home/ubuntu/
but the above command will only copy the *_F.jpg files and not their respective parent directories GJ1.
Is xargs not the one im supposed to try?
I have also tried -
find . -name "*_F.jpg" -exec sh -c 'rsync -a "${0%/*}" ~/home/ubuntu/' {} \;
One easy way is to use tar which will deal with the directories automatically:
find . -type f -name "*_F.jpg" -print0 | tar c --null -T - | tar xC ~/home/ubuntu/
And here's a solution with a while loop:
find . -type f -name "*_F.jpg" -print0 |
while IFS= read -r -d '' file; do
mkdir -p ~/home/ubuntu/"$(dirname -- "$file")"
cp -ai -- "$file" ~/home/ubuntu/"$file"
done

create a list with content of multiple zip files in linux

I am trying to create a script for linux that will make a list with all files inside all zip files from a directory.
#! /bin/bash
for file in `find /home -iname "*.zip*" -type f`
do
unzip -l $(echo ${file}) >> /home/list.txt
done
It works, but only when there are no white spaces in filename.
What can I do to make it work ?
You can use the find command to execute a command for each file it finds. Perhaps try something like:
find /home -iname "*.zip*" -type f -exec unzip -l {} \; > /home/list.txt

Create file in Linux and replace content

I have a project in Linux. I want to create a file named index.html in all folders.
So I have used the following command:
find . -type d -exec touch {}/index.html \;
It's working! Now I'm trying to copy the existing file from a given location and it to be automatically replaced into all the folders of my project.
This should actually work exactly in the same way:
find . -type d -exec cp $sourcedir/index.html {}/index.html \;
If I understand your question correctly, what you want is to copy a given file in all the directories.
You can use a similar find command :
find . -type d -exec cp -f /tmp/index.html {} \;
where /tmp/index.html is path to the original file (replace it with your own path).
Also, you don't need to create the files if your final objective is to replace them with the original file.
tar -cvzf index.tar.gz `find . -type f -iname 'index.html'` && scp index.tar.gz USER#SERVER:/your/projec/root/on/SERVER && ssh USER#SERVER "tar -xvzf index.tar.gz"
Or if you're in the proper directory localhost, and rsync is available:
rsync -r --exclude='**' --include='**/index.html' . USER#SERVER:/your/projec/root/on/SERVER
HTH

unzip specific extension only

I have a a directory with zip archives containing .jpg, .png, .gif images. I want to unzip each archive taking the images only and putting them in a folder with the name of the archive.
So:
files/archive1.zip
files/archive2.zip
files/archive3.zip
files/archive4.zip
Open archive1.zip - take sunflower.jpg, rose_sun.gif. Make a folder files/archive1/ and add the images to that folder, so files/archive1/folder1.jpg, files/archive1/rose_sun.gif. Do this to each archive.
I really don't know how this can be done, all suggestions are welcome. I have over 600 archives and an automatic solution would be a lifesaver, preferably a linux solution.
In Short
You can do this with a one-liner find + unzip.
find . -name "*.zip" -type f -exec unzip -jd "images/{}" "{}" "*.jpg" "*.png" "*.gif" \;
In Detail
unzip allows you to specify the files you want:
unzip archive.zip "*.jpg" "*.png" "*.gif"
And -d a target directory:
unzip -d images/ archive.zip "*.jpg" "*.png" "*.gif"
Combine that with a find, and you can extract all the images in all zips:
find . -name "*.zip" -type f -exec unzip -d images/ {} "*.jpg" "*.png" "*.gif" \;
Using unzip -j to junk the extraction of the zip's internal directory structure, we can do it all in one command. This gives you the flat image list separated by zip name that you desire as a one-liner.
find . -name "*.zip" -type f -exec unzip -jd "images/{}" "{}" "*.jpg" "*.png" "*.gif" \;
A limitation is that unzip -d won't create more than one new level of directories, so just mkdir images first. Enjoy.
7zip can do this, and has a Linux version.
mkdir files/archive1
7z e -ofiles/archive1/ files/archive1.zip *.jpg *.png *.gif
(Just tested it, it works.)
Something along the lines of:
#!/bin/bash
cd ~/basedir/files
for file in *.zip ; do
newfile=$(echo "${file}" | sed -e 's/^files.//' -e 's/.zip$//')
echo ":${newfile}:"
mkdir tmp
rm -rf "${newfile}"
mkdir "${newfile}"
cp "${newfile}.zip" tmp
cd tmp
unzip "${newfile}.zip"
find . -name '*.jpg' -exec cp {} "../${newfile}" ';'
find . -name '*.gif' -exec cp {} "../${newfile}" ';'
cd ..
rm -rf tmp
done
This is tested and will handle spaces in filenames (both the zip files and the extracted files). You may have collisions if the zip file has the same file name in different directories (you can't avoid this if you're going to flatten the directory structure).
You can write a program using a zip library. If you do Mono, you can use DotNetZip.
The code would look like this:
foreach (var archive in listOfZips)
{
using (var zip = ZipFile.Read(archive)
{
foreach (ZipEntry e in zip)
{
if (IsImageFile(e.FileName))
{
e.FileName = System.IO.Path.Combine(archive.Replace(".zip",""),
System.IO.Path.GetFileName(e.FileName));
e.Extract("files");
}
}
}
}
Perl's Archive-Zip is a good library for zipping/unzipping.
Here's my take on the first answer...
#!/bin/bash
cd files
for zip_name in *.zip ; do
dir_name=$(echo "${zip_name}" | sed -e 's/^files.//' -e 's/.zip$//')
mkdir ${dir_name}
7z e -o${dir_name}/ ${zip_name} *.jpg *.png *.gif
done
or, if you'd just like to use the regular unzip command...
unzip -d ${dir_name}/ ${zip_name} *.jpg *.png *.gif
I haven't tested this, but it should work... or something along these lines. Definitely more efficient than the first solution. :)
Hope this helps!

Resources