How to tar specific file extension files? - include

I have file types .cpp,.h,.o,.so,*.a
I need to tar only *.cpp and .h files.
as of now i am using --exclude=.{o,so,a} unwanted files to tar.
but if i have many unwanted extensions the exclude list comes very big.
what is the command to include specific file extensions to tar?

find -name "*.h" -o -name "*.cpp" | xargs tar -czvf build.tar.gz

Related

How to tar compress specific and multiple files without changing of name in Bash?

I need do some simple compresion multiple files to .tar in bash.
Conditions:
My archive must include only files with extension .exe.
Unfortunetly, when I am trying this:
find ./myDir -name "*.exe" | tar -cf archive -T -
The file names are changed like ./file1.exe How can I compress this without change of file names?
Suggesting:
find "$PWD/myDir" -name "*.exe" | tar -cf archive -T -
This will not do anything interesting.
Better suggesting to feed tar command with results from find command
tar czf your_compressed_file.tar.gz $(find ./myDir -name "*.exe")
Notice tar cf is not compressed. But tar czf is compressed.
You can also add -v option to see what are the compressed files:
tar czfv your_compressed_file.tar.gz $(find ./myDir -name "*.exe")

bash: list files that are not with a given extension

I was wondering if there is a way to ls files in a folder that does not have a given extension? For example, if I have a folder full of .cpp and .h files, and I wanted to see if there are other types of files (such as config files and make files), how do I list or find?
Thanks,
You can use find:
find . -maxdepth 1 ! \( -name "*.cpp" -o -name "*.h" \)
shopt -s extglob
ls *!(.cpp|.h)
Pipe through an appropriate grep, e.g.:
ls | grep -Ev '\.(cpp|h)$'

How to search subdirectories for .c files and compile them (shell scripting)

I need to take an argument which is a directory of the current directory and search its folders and compile any C files in those folders. I'm just beginning shell scripting in Bash and am a little over my head.
So far things I've tried included using find to search for the files and then pipe it to xargs to compile but kept getting an error saying that testing.c wasn't a directory.
find ~/directory -name *.c | xargs gcc -o testing testing.c
I've also tried ls -R to search folders for .c files but don't know how to then take the paths as arguments to then move to and compile?
find ~/directory -type f -name "*.c" -print0 |
while IFS= read -r -d '' pathname; do
gcc -o "${pathname%.c}" "$pathname"
done
find directory -type f -name "*.c" -exec sh -c \
'cd $(dirname $1);make $(basename $1 .c)' sh {} \;
As #shx2 suggested, using make (or some other build system) would arguably be the best approach. You don't want to go compiling files in some source tree without a proper build system.

Unix tar: do not preserve full pathnames

When I try to compress files and directories with tar using absolute paths, the absolute path is preserved in the resulting compressed file. I need to use absolute paths to tell tar where the folder I wish to compress is located, but I only want it to compress that folder – not the whole path.
For example, tar -cvzf test.tar.gz /home/path/test – where I want to compress the folder test. However, what I actually end up compressing is /home/path/test. Is there anything that can be done to avoid this? I have tried playing with the -C operand to no avail.
This is ugly... but it works...
I had this same problem but with multiple folders, I just wanted to flat every files out. You can use the option "transform" to pass a sed expression and... it works as expected.
this is the expression:
's/.*\///g' (delete everything before '/')
This is the final command:
tar --transform 's/.*\///g' -zcvf tarballName.tgz */*/*.info
Use -C to specify the directory from which the files look like you want, and then specify the files as seen from that directory:
tar -cvzf test.tar.gz -C /home/path test
multi-directory example
tar cvzf my.tar.gz example.zip -C dir1 files_under_dir1 -C dir2 files_under_dir2
the files under dir 1/2 should not have path.
tar can perform transformations on the filenames on the way in and out of the archive. Consider this example that stores a bunch of files in a flat tarfile:
in the root ~/ directory
find logger -name \*.sh | tar -cvf test.tar -T - --xform='s|^.*/||' --show-transformed
The -T - option tell tar to read a list of files from stdin, the --xform='s|^.*/||' applies the sed expression to all the filenames as after they are read and before they are stored. --show-transformed is just a nicety to show you the file names after they are transformed, the default is to show the names as they are read.
There are no doubt other ways besides using find to specify files to archive. For instance, if you have dotglob set in bash, you can use ** patterns to wildcard any number of directories, shortening the previous to this:
tar -cvf test.tar --xform='s|^.*/||' --show-transformed logger/**/*.sh
You’ll have to judge what is best for your situation given the files you’re after.
find -type f | tar --transform 's/.*\///g' -zcvf comp.tar.gz -T -
Where find -type f finds all the files in the directory tree and using tar with --transform compresses them without including the folder structure. This is very useful if you want to compress only the files that are the result of a certain search or the files of a specific type like:
find -type f -name "*.txt" | tar --transform 's/.*\///g' -zcvf comp.tar.gz -T -
Unlike the other answers, you don't have to include */*/* specifying the depth of the directory. find handles that for you.

Making archive from files with same names in different directories

I have some files with same names but under different directories. For example, path1/filea, path1/fileb, path2/filea, path2/fileb,....
What is the best way to make the files into an archive? Under these directories, there are many other files under these directories that I don't want to make into the archive. Off the top of my head, I think of using Bash, probably ar, tar and other commands, but am not sure how exactly to do it.
Renaming the files seems to make the file names a little complicated. I tend to keep the directory structure inside the archive. Or I might be wrong. Other ideas are welcome!
Thanks and regards!
EDIT:
Examples would be really nice!
you can use tar with --exclude PATTERN option. See the man page for more.
To exclude files, you can see this page for examples.
You may give the find command multiple directories to search through.
# example: create archive of .tex files
find -x LaTeX-files1 LaTeX-files2 -name "*.tex" -print0 | tar --null --no-recursion -uf LaTeXfiles.tar --files-from -
To recursively copy only files with filename "filea" or "fileb" from /path/to/source to /path/to/archive, you could use:
rsync -avm --include='file[ab]' -f 'hide,! */' /path/to/source/ /path/to/archive/
'*/' is a pattern which matches 'any directory'
'! */' matches anything which is not a directory (i.e. a file)
'hide,! */' means hide all files
Filter rules are applied in order, and the first rule that matches is applied.
--include='file[ab]' has precedence, so if a file matches 'file[ab]', it is included.
Any other file gets excluded from the list of files to transfer.
Another alternative is to use the find...exec pattern:
mkdir /path/to/archive
cd /path/to/source
find . -type f -iname "file[ab]" -exec cp --parents '{}' /path/to/archive ";"
What I have used to make a tar ball for the files with same name in different directories is
$find <path> -name <filename> -exec tar -rvf data.tar '{}' \;
i.e. tar [-]r --append
Hope this helps.

Resources