Linux Shell Script execute without save to temporary variable - linux

If I want to execute a command with variables in it, I always have to store the string first in a variable and then can execute it...
Example:
path_fasta="/home/xxx/yyy/zzz/qqq/"
name_fasta="CTA_Mix_DNA.fna"
path_outp"/some/Path/"
temp='find . -maxdepth 1 -not -name '$name_fasta' -not -name letsgo.sh -delete'
$temp
temp=$path_mothur'mothur #set.dir(output='$path_outp');summary.seqs(fasta='$path_fasta''$name_fasta')'
$temp
How do I do this directly without storing it first in temp? Must be easy, but did not find a solution...

Instead of:
temp='find . -maxdepth 1 -not -name '$name_fasta' -not -name letsgo.sh -delete'
$temp
...just use:
find . -maxdepth 1 -not -name "$name_fasta" -not -name letsgo.sh -delete

Related

Linux find -type f ignored

I'm creating a cron job, that will find all *.log* files (it will be used to remove them later, when it works).
The find command looks like this:
find /data/dg \( -path /data/dg/kf/data -o -path /data/dg/pg/data \) -prune -o -name "*.log*" -type f
And it should find all files with name ".log" that are not in directories /data/dg/kf/data and /data/dg/pg/data
However the output this command gives contains also the directories.
...
/data/dg/kf/log/controller.log.2019-09-08-22
/data/dg/kf/log/server.log.2019-09-09-07
/data/dg/kf/data
/data/dg/pg/log/postgresql-2019-09-27_000000.log
/data/dg/pg/log/postgresql-2019-09-27_100859.log
/data/dg/pg/log/postgresql-2019-09-27_102411.log
/data/dg/pg/data
/data/dg/sim/log/sim_2019-09-27-11.0.log
/data/dg/sim/log/sim_2019-09-27-12.0.log
...
It seems that -type f doesn't work. What's wrong?
put -type f right after /data/dg
find /data/dg -type f -not -path "/data/dg/kf/data*" -not -path "/data/dg/pg/data*" -name "*.log*"

How display only files inside subdirs using the -haltr format?

How do I add the output looks of ls -haltr into the command below?
find 20180913/ -maxdepth 5 -not -type d -and -not -name '.*'
Basically I am trying to list only files inside my subdirs but need to display the file time stamp sorted by date with latest at the bottom.
Thank you
You can try using the exec option of find:
find 20180913/ -maxdepth 5 -not -type d -and -not -name '.*' -exec ls -haltr {} +
Updated my answer based on PesaThe's correction.

Exclude list of file extensions from find in bash shell

I want to write a cleanup routine for my make file that removes every thing except the necessary source files in my folder. For example, my folder contains files with the following extensions: .f .f90 .F90 .F03 .o .h .out .dat .txt .hdf .gif.
I know I can accomplish this with:
find . -name \( '*.o' '*.out' '*.dat' '*.txt' '*.hdf' '*.gif' \) -delete
Using negation, I can do this:
find . -not -name '*.f*' -not -name '*.F*' -not -name '*.h' -delete
But, when I try to do this:
find . -not -name \( '*.f*' '*.F*' '*.h' \)
I get an error:
find: paths must exceed expression: [first expression in the above list]
(In this case, I would get:
find: paths must exceed expression: *.f*
)
Can you explain why this happens, and how to do what I am trying to do? I just hate writing -not -name every time I want to add a file extension to the list. Also, I want to find out why this is giving me an error so that I can learn Linux better.
Thanks!
find . -not -name \( '*.f' '*.F' '*.h' \)
is interpreted as
find
. # path to search
-not # negate next expression
-name \( # expression for files named "("
'*.f' '*.F' .'*.h' \) # more paths to search?
leading to the error.
Since these are single-letter extensions, you can collapse them to a single glob:
find . -not -name '*.[fFh]'
but if they are longer, you have to write out the globs
find . -not -name '*.f' -not -name '*.F' -not -name '*.h'
or
find . -not \( -name '*.f' -o -name '*.F' -o -name '*.h' \)
or switch to using regular expressions.
find . -not -regex '.*\.(f|F|h)$'
Note that regular expressions in find is not part of the POSIX standard and might not be available in all implementations.

How to remove certain pattern files except another certain pattern files from a list?

I have many file with name chr1_gene_*.raw. I would like to keep some of them. So I use following command.
find . -maxdepth 1 -type f -name "*.raw" -not -name "chr1_gene_448.raw" -not -name "chr1_gene_1914.raw" -not -name "chr1_gene_2456.raw" -not -name "chr1_gene_1554.raw" -not -name "chr1_gene_2024.raw" -not -name "chr1_gene_35.raw" -not -name "chr1_gene_509.raw" -not -name "chr1_gene_1952.raw" -not -name "chr1_gene_575.raw" -not -name "chr1_gene_2249.raw" -not -name "chr1_gene_272.raw" -not -name "chr1_gene_2158.raw" -exec rm -rf {} \;
Sometimes there are too many files I want to keep. I do not want to type "-not -name " too many times. Is there a way to put a list in "-not -name"?
You may achieve this using a script say notnamescript.sh :
#!/bin/bash
while read line
do
echo "-not -name " $line
done<notnamelist
Put all the -not -name names in a file called notnamelist. Remember there
should be no trailing empty lines.
find . -maxdepth 1 -type f -name "*.name" $( ./notnamescript.sh ) -exec rm -rf {} \;

linux find command is not taking proper argument

find . -maxdepth 1 ! -path . -type f ! -name "*.gz" ${FILE_PATTERN} -mtime +${DAYS_AFTER_ARCHIVE}
I am trying to execute above command inside the script where ${FILE_PATTERN} and ${DAYS_AFTER_ARCHIVE} are the variable provided while executing the script. The variable value for ${FILE_PATTERN} would be ! -name "*warnings*".
I am looking for executing above command as like below command in script
find . -maxdepth 1 ! -path . -type d ! -name "*warnings*" -mtime +7
I am providing file pattern argument as "! -name "warnings""
but receiving following error message
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]
suggest on above.
First of all
-name "*.gz" ${FILE_PATTERN}
has too many option values (this is what usually causes the message shown)
If you use bash or similar, escape the exclamation marks
find . -maxdepth 1 \! -path . -type f \! -name "*.gz" ${FILE_PATTERN} -mtime +${DAYS_AFTER_ARCHIVE}
I am providing file pattern argument as "! -name "warnings"" but receiving following error message
You can't combine flags and their values like that. Also, you can't nest " like that. So, it could be like
! -name "$FILE_PATTERN"
If you're using BASH you can make use of BASH arrays:
# find options
FILE_PATTERN=(! -name "warnings*")
# build the find command
cmd=(find . -maxdepth 1 ! -path . -type f \( ! -name "*.gz" "${FILE_PATTERN[#}}" \) -mtime +${DAYS_AFTER_ARCHIVE})
# execute the command
"${cmd[#]}"
If not using BASH then you will have to use eval with caution:
FILE_PATTERN='! -name "warnings*"'
eval find . -maxdepth 1 ! -path . -type f ! -name "*.gz" "${FILE_PATTERN}" -mtime +${DAYS_AFTER_ARCHIVE}

Resources