for loop to echo the sequential command lines? - linux

how to use for loop in linux to generate the following lines?
zcat ~/tools/sample66621D.fastq | bowtie2 -a - | samtools ->sample66621D.BAM
zcat ~/tools/sample66622D.fastq | bowtie2 -a - | samtools ->sample66622D.BAM
zcat ~/tools/sample66623D.fastq | bowtie2 -a - | samtools ->sample66623D.BAM
I've tried:
for ((a=21;a<=23;a++))
echo "zcat ~/tools/sample666$aD.fastq | bowtie2 -a - | samtools ->sample666$aD.BAM"
done
but it turned to be three identical lines .
zcat ~/tools/sample666.fastq | bowtie2 -a - | samtools ->sample666.BAM
zcat ~/tools/sample666.fastq | bowtie2 -a - | samtools ->sample666.BAM
zcat ~/tools/sample666.fastq | bowtie2 -a - | samtools ->sample666.BAM
thanks

$aD is a valid variable name. You must delimit the variable name with brackets, i.e. ${a}.

Related

How do I use to pass output from command as parameter to another (complex)?

I am trying to somewhat automate the certificate bundle update on the F5 devices.
There is not one command that can check for SSL bundle expiry and match it to the server SSL profile name. So I am trying to do it with greps (as its all I know =)
There are two commands:
tmsh -c "cd /;list sys file ssl-cert recursive is-bundle expiration-string" | grep true -B 2 | grep "2018 GMT\|2019 GMT\|2020 GMT\|2021 GMT\|2022 GTM" -B 1 | grep ssl-cert | awk -F[\ \{] '{print $4}'
This will give an output of expired bundle names, one on each line, like this
Common/somebundle.crt
Common/someotherbundlename.crt
Common/whoknowswhatthisbundleisfor.crt
tmsh -c 'cd /;list ltm profile server-ssl recursive ca-file chain'
This command will get a list of all server-ssl profile names and its links to certs/bundles etc. I am them using | grep Common/somebundle.crt -B 1 to only give me info about a particular output from the command 1 output. So command 2 becomes:
tmsh -c 'cd /;list ltm profile server-ssl recursive ca-file chain' | grep Common/somebundle.crt -B 1
Then I have to manually repeat for each of the found bundles in command 1 output.
I am trying to somehow use command 1 and then either xargs (or whatever I can) to run the command 2, passing the output from 1 into the grep in 2
It does not have to be one-liner, I just dont know bash enough to write a script
I have created something that works, though not very clean looking =)
for i in $(tmsh -c "cd /;list sys file ssl-cert recursive is-bundle expiration-string" | grep true -B 2 | grep "2018 GMT\|2019 GMT\|2020 GMT\|2021 GMT\|2022 GTM" -B 1 | grep ssl-cert | awk -F[\ \{] '{print $4}'); do echo -n "$i -> "; tmsh -c "cd /;list ltm profile server-ssl recursive" | grep -B20 $i >> /dev/null || echo "Not Found" && tmsh -c "cd /;list ltm profile server-ssl recursive" | grep -B20 $i |grep -i "ltm profile" | tail -n1 | awk -F "{" '{print $1}' ; done
It should be possible with bash while loop and read function. You can pipe your first command into while loop, reading line-by-line your output:
tmsh -c "cd /;list sys file ssl-cert recursive is-bundle expiration-string" | grep true -B 2 | grep "2018 GMT\|2019 GMT\|2020 GMT\|2021 GMT\|2022 GTM" -B 1 | grep ssl-cert | awk -F[\ \{] '{print $4}' | while read bundle;do tmsh -c 'cd /;list ltm profile server-ssl recursive ca-file chain' | grep "$bundle" -B 1 |...do whatever else is needed ;done
It also can be splitted into normal multiline script:
tmsh -c "cd /;list sys file ssl-cert recursive is-bundle expiration-string" | grep true -B 2 | grep "2018 GMT\|2019 GMT\|2020 GMT\|2021 GMT\|2022 GTM" -B 1 | grep ssl-cert | awk -F[\ \{] '{print $4}' | while read bundle
do
echo "===== $bundle ===="
tmsh -c 'cd /;list ltm profile server-ssl recursive ca-file chain' | grep "$bundle" -B 1 |...do whatever else is needed
done

batch file to read file contents and iterate

I am trying to write a batch file/shell script that reads the contents of a file, matches those contents with a directory structure and invokes an executable file.
Let's say there is a sequence.txt file in /system/ directory. The sequence file is to represent or force the order of execution. This is important
The sequence.txt file has following enteries:
1;schema1;procedures
1;schema1;functions
2;schema2;procedures
2;schema2;functions
........
and then there is a directory, and the directory has following subdirs
/scripts
| +--/schema1
| | +--/procedures
| | | --1.sql
| | | --2.sql
| | +--/functions
| | | --1.sql
| | | --2.sql
| | +--/packages
| | | --1.sql
| | | --2.sql
| | +--/logs
| +--/schema2
| | +--/procedures
| | | --1.sql
| | | --2.sql
| | +--/functions
| | | --1.sql
| | | --2.sql
| | +--/packages
| | | --1.sql
| | | --2.sql
| | +--/logs
.......
........
Now I would like to run flyway (a database migration software) in a loop using this way:
Flyway -schema=schema1 -locations=/scripts/schema1/procedures, /scripts/schema1/functions, /scripts/schema1/packages migrate -x | tee /scripts/schema1/log/logfile_ddmmyy.log
Flyway -schema=schema2 -locations=/scripts/schema2/procedures, /scripts/schema2/functions, /scripts/schema2/packages migrate -x | tee /scripts/schema2/log/logfile_ddmmyy.log
So far this is my progress:
#!/bin/bash
while read i;
do echo "$i";
done < ./system/sequence.txt
How can I proceed further? I know that this kind of scripting involves variables and then loops but I can't find a way to translate it into technical level.
Cheers and thanks in advance! :-)
Though not completely clear about what you want, here is some inspiration:
while read line; do
OIFS=$IFS
IFS=';'
a=()
for name in ${line}; do
a+=(${name})
done
IFS=$OIFS
number=${a[0]}
schema=${a[1]}
subdir=${a[2]}
echo "Flyway -schema=${schema} -locations=/scripts/${schema}/procedures, /scripts/${schema}/functions, /scripts/${schema}/packages migrate -x | tee /scripts/${schema}/log/logfile_ddmmyy.log"
done <<EOF
1;schema1;procedures
1;schema1;functions
2;schema2;procedures
2;schema2;functions
EOF
It doesn't exexute Flymake, it just echo the Flymake commands.
It uses the special variable $IFS to do the magic.
Fit it to your needs.
output
Flyway -schema=schema1 -locations=/scripts/schema1/procedures, /scripts/schema1/functions, /scripts/schema1/packages migrate -x | tee /scripts/schema1/log/logfile_ddmmyy.log
Flyway -schema=schema1 -locations=/scripts/schema1/procedures, /scripts/schema1/functions, /scripts/schema1/packages migrate -x | tee /scripts/schema1/log/logfile_ddmmyy.log
Flyway -schema=schema2 -locations=/scripts/schema2/procedures, /scripts/schema2/functions, /scripts/schema2/packages migrate -x | tee /scripts/schema2/log/logfile_ddmmyy.log
Flyway -schema=schema2 -locations=/scripts/schema2/procedures, /scripts/schema2/functions, /scripts/schema2/packages migrate -x | tee /scripts/schema2/log/logfile_ddmmyy.log
I am not sure about the exact relation betwen values and final command path but awk is the tool to construct the call. Use somethin like:
c = `echo $i | awk -F ";" '{print "flyway" $1 "_" $2}'
where $x is the position of the value and you can construct a string.
After that you can run the c var with
`echo $c`
That should work.
UPDATED:
If I understand correctly what you need, you have to set two whiles, one inside the other. Something like this:
cat tt.txt | awk -F";" '{print $1}'| sort -u | while read i
do
sc = `grep $i tt.txt | head -n 1 | awk -F";" '{print $2}'`
pt1 = "Flyway -schema=" $sc " -locations="
pt3 = " -x | tee /scripts/" $sc "/log/logfile_ddmmyy.log"
grep $i tt.txt | while read j
do
c=`echo $j | awk -F";" '{print $2}'| sort -u`
pt2 = $pt2 "/scripts/" $sc "/" $c ""
done
echo $pt1 $pt2 $pt3
done

xargs -I % /path/ %

If torrent has a problem like deleted data on hard drive in id column it has number like "ID*".
I want to filter IDs of torrents in torrent list which have a symbol "*" at the end of id(LIKE ID* or 1*,2*,25*) and delete them from torrent list.
Full command is:
/usr/bin/transmission-remote 127.0.0.1:9091 --auth ts:ts -l | grep "*" | awk '{print $1}' \
| xargs -n 1 -I % /usr/bin/transmission-remote 127.0.0.1:9091 --auth ts:ts -t% -r
I expected result:
/usr/bin/transmission-remote 127.0.0.1:9091 --auth ts:ts -t ID* -r
But something went wrong.
Transmission said that:
127.0.0.1:9091/transmission/rpc/ responded: "success"
But torrent didn't delete from list.
How I can see the final result to compare with expected?
To get IDs :
transmission-remote -l | grep '*' | awk '{print $1}' | grep -o '[0-9]*'
The full command :
transmission-remote -l | grep '*' | awk '{print $1}' | grep -o '[0-9]*' | tr "\\n" "," | xargs -n 1 -I \% transmission-remote -t \% -r
Done and done (:
With the added improvement of using "tr" to join all torrent IDs and avoid running everything in a loop ( Transmission-RPC is extremely resource intensive to call repeatedly )

Command substitution as a variable in one-liner

I get the following error:
> echo "${$(qstat -a | grep kig):0:7}"
-bash: ${$(qstat -a | grep kig):0:7}: bad substitution
I'm trying to take the number before. of
> qstat -a | grep kig
1192530.perceus- kigumen lr_regul pbs.sh 27198 2 16 -- 24:00:00 R 00:32:23
and use it as an argument to qdel in openPBS so that I can delete all process that I started with my login kigumen
so ideally, this should work:
qdel ${$(qstat -a | grep kig):0:7}
so far, only this works:
str=$(qstat -a | grep kig); qdel "${str:0:7}"
but I want a clean one-liner without a temporary variable.
The shell substring construct you're using (:0:7) only works on variables, not command substitution. If you want to do this in a single operation, you'll need to trim the string as part of the pipeline, something like one of these:
echo "$(qstat -a | grep kig | sed 's/[.].*//')"
echo "$(qstat -a | awk -F. '/kig/ {print $1}')"
echo "$(qstat -a | awk '/kig/ {print substr($0, 1, 7)}')"
(Note that the first two print everything before the first ".", while the last prints the first 7 characters.) I don't know that any of them are particularly cleaner, but they do it without a temp variable...
qstat -u palle | cut -f 1 -d "." | xargs qdel
Kills all my jobs... normally I grep out the jobname(s) before cut'ing...
So I use a small script "idlist":
qstat -u palle | grep -E "*.in" | grep -E "$1" | cut -f 1 -d "." | xargs
To see all my "map_..." jobs:
idlist "map_*"
For killing all my "map_...." jobs:
idlist "map_*" | xargs qdel
yet another ways :
foreach m1 in $(qstat -a );do
if [[ $m1 =~ kig ]];then
m2=${m1%.kig}
echo "kig found $m2 "
break
fi
done

Pipe to command that does not accept piping

I want to use MPC (CLI interface to MPD) but unfortunately to me it does not accept piping.
So something like:
ll | grep "pattern" | sed 's/this/that/' | mpc
does not work for me, nor
ll | grep "pattern" | sed 's/this/that/' | mpc -
This
MPCTMP=`ll | grep "pattern" | sed 's/this/that/'` && echo $MPCTMP
works as expected, but this:
MPCTMP=`ll | grep "pattern" | sed 's/this/that/'` && mpc $MPCTMP
does not return results, variable is not understood but this program
I'm new to Linux and could not find anything searching with Google
Thanks
Try xargs
ll | grep "pattern" | sed 's/this/that/' | xargs mpc

Resources