how to put all folders that do not have 'AAA' or 'BBB' in name into a zip file ? linux - linux

In the current folder I have lots of subfolders and they have files in them. How can I put those folders with no AAA or BBB in the name into a .zip file?
123AAAcc
123.txt
BBB.csv
222BBBss
...
ADFAAA
BBB
adsf.txt
vvBB
111.mov
BBB.avi
I've tried the following and it also excludes vvBB\BBB.avi and ADFAAA\BBB\*. I would like to keep those.
tar -zcvf test.tgz --exclude='*AAA*' --exclude='*BBB*' .
The problem is, how can I have --exclude only work on level 1 subfolder names, but recursively on all filenames and folder names?
Hopefully I have a .zip file containing:
vvBB
111.mov
BBB.avi
I would like to achieve this as one command line. How can I do this?

You can accomplish this behavior by chaining together the following commands:
ls will list all of the files and folders in the current directory.
grep -v "\(.*BBB.*\)\|\(.*AAA.*\)" looks for all names with AAA or BBB (surrounded by anything), then (with -v) excludes them and returns all other results.
xargs tar -cvzf test.tgz will take arguments from a pipe and apply them to tar. All together, you get:
ls | grep -v "\(.*BBB.*\)\|\(.*AAA.*\)" | xargs tar -cvzf test.tgz
The partial results I get are:
$ ls
123AAAcc
222BBBss
ADFAAA
vvBB
$ ls | grep -v "\(.*BBB.*\)\|\(.*AAA.*\)"
vvBB
$ ls | grep -v "\(.*BBB.*\)\|\(.*AAA.*\)" | xargs tar -cvzf test.tgz
a vvBB
a vvBB/111.mov
a vvBB/BBB.avi

Related

How to use xargs curl to read lines of a text file in subdirectory and keep downloaded files in subdirectory?

I have several subdirectories within a parent folder, each with a URLs.txt file within the subdirectory.
$ ls
H3K4me1_assay H3K4me2_assay H3K4me3_assay ... +30 or so more *_assay files
Each assay_file contains one URLs.txt file:
$ cat URLs.txt
https://www.encodeproject.org/files/ENCFF052HMX/##download/ENCFF052HMX.bed.gz
https://www.encodeproject.org/files/ENCFF052HMX/##download/ENCFF052HMX.bed.gz
https://www.encodeproject.org/files/ENCFF466DMK/##download/ENCFF466DMK.bed.gz
... +200 or more URLs
Is there any way I can execute a command from the parent folder that reads and curls the URLs.txt file in each subdirectory, and then downloads the file within each subdirectory?
I can cd into each file and run the following commands to download all of the files:
$ cd ~/largescale/H3K4me3_assay
$ ls URL* | xargs -L 1 -d '\n' zcat | xargs -L 1 curl -O -J -L
But I will have to run this command for experiments with +300 folders, so cd'ing in each time isn't really practical.
I have tried to run this, it does download the correct files but within the parent folder rather than the subdirectories. Any idea what I am doing wrong?
$ for i in ./*_assay; do cd ~/largescale/"$i" | ls URL* | xargs -L 1 -d '\n' zcat | xargs -L 1 curl -O -J -L; done
Thanks, Steven

How to copy files filtered with grep

I need find and copy files in /usr/share/man
Especialy need man7-8 and everything that have "et" in name.
I try this:
ls man7 man8 | grep "et"
This works perfectly.
Than i want that files copy with cp but i dont know how to format it properly
ls man7 man8 | grep "et" | xargs -I '{}' cp '{}' /home/marty/homework
But this is not working
It's not working because ls directory just outputs the filenames, without the directory prefixes. So cp doesn't know what directory to copy the file from.
But there's need for ls or grep, just use a wildcard.
cp man7/*et* man8/*et* /home/marty/homework
Your code would also fail for any filenames containing whitespace, since xargs treats that as a delimiter by default.

'ls | grep -c' and full path

Can I use ls | grep -c /full/path/to/file to count the occurrences of a file, but while executing the command from a different directory than where the files I'm looking for are?
Let's say I want to look how many .txt files I have in my "results" directory. Can I do something like ls | grep -c /full/path/to/results/*.txt while I'm in another directory?
Although I have .txt files in that directory, I always get a zero when I run the command from another directory :( What's happening? Can I only use ls for the current directory?
You have to use ls <dirname>. Plain ls defaults only to the current directory.
What you are trying to do can be accomplished by find <dir> -name "*.txt" | grep -c txt or find <dir> -name "*.txt" | wc -l
But you can do ls * | grep \.txt$ as well. Please read the manual to find the differences.
grep accepts regular expressions, not glob. /foo/bar/*.txt is a glob. Try /foo/bar/.*\.txt
also ls lists files and directories under your current directory. It will not list the full path. Do some tests, and you will see it easily.
ls may output results in a single line, and this could make your grep -c give an incorrect result. Because grep does line-based matching.

Listing multiple files in a specific format in BASH

I have lots of files in a directory and I want to list all files in a specific format by creating date order (newer files first)
I can do this with stat and sort in the directory of files:
Commands:
cd /path
stat -c '%.19y %n' * | sort -nr
Output:
2014-01-25 16:44:52 Filename1.txt
2014-01-24 16:34:17 Filename2.txt
It is fine. This is what I want exactly.
But when I try to run outside of the directory, command shows filenames with /path
Commands:
cd /
stat -c '%.19y %n' /path/* | sort -nr
Output:
2014-01-25 16:44:52 /path/Filename1.txt
2014-01-24 16:34:17 /path/Filename2.txt
How can I list file names without path?
Provided you have GNU find, you can use that instead
find /path -printf '%TY-%Tm-%Td %TH:%TM:%.2TS %f\n'
2015-10-12 04:54:24 file

Use grep -lr output to add files to tar

In UBUNTU and CENTOS.
I have some files I want to tar based on their contents.
$ grep -rl "123.45" .
returns a list of about 10 files in this kind of format:
./somefolder/someotherfolder/somefile.txt
./anotherfolder/anotherfile.txt
etc...
I want to tar.gz all of them.
I tried:
$ grep -rl "123.45" . | tar -czf files.tar.gz
Doesn't work. That's why I'm here. Any ideas? Thanks.
Just tried this, and it worked in Ubuntu, but in CentOS I get "tar: 02: Cannot stat: No such file or directory".
$ tar -czf test.tar.gz `grep -rl "123.45" .`
If anyone else has a better way, let me know. That above one works great in Ubuntu, at least.
Like this:
... | tar -T - -czf files.tar.gz
"-T -" causes tar to read filenames from stdin. Second minus stands for stdin. –
grep -rl "123.45" . | xargs tar -czf files.tar.gz
Tar wants to be told what files to process, not given the names of the files via stdin.
It does however have a -T / --files-from option. So I'd suggest using that. Output your list of selected files to a temp file and then have tar read that, like this:
T=$(mktemp)
grep -rl "123.45" . > $T
tar cfz files.tar.gz -T $T
rm -f $T
If you want, you can also use shell expansion to do it like this:
tar cfz files.tar.gz -- $(grep -rl "123.45" .)
But that will fail if you have too many files or if any of the files have strange names (like spaces etc).

Resources