Weird characters when I print a number into a file (bash shell) - bash

I have this line in my script.sh
printf "%d" "$endMS_line"
$endMS_line is a number. I get that number with
endMS_line=`cat file | awk '{if($1=='"$variable"') print NR}'`
And to print it I use
printf "%d" "$endMS_line"
or
echo $endMS_line
So everything works perfectly in the standard output. The problem is when I want to save that number into a file (because I want to use the result in another script, may be there is a clever way to do it than write a file and then read the number from the file, etc..)
But for now I am trying to do that. How? Well I write this in the standard output.
myscript.sh inputs > file.txt
But when I try to see the file (when I open the file) I see the result plus weird characteres
[H[2J867
The correct number in this example is 867. Anyone know how can I fix this?
Thank you!

At the begginning of the script I had the command:
clear
removing that and using:
echo "$endMS_line"
Then in the standard output:
myscript.sh input > file.txt
works perfectly.

Related

How to append output in bash?

I have a shell command that produces line based output. Let me call it magic for the sake of the argument. For whatever output it produces, how can I just append another value to it? I would like to do it in a pipe. I tried for a long time to google this without any luck. It seems like I must be missing some obvious way to do it. Ideally, there would be another unix command called append which given as standard input the output of any other command the same output along with its arguments.
What I am imagining:
magic
This returns:
apple
cherry
banana
magic | append taro
This returns:
apple
cherry
banana
taro
Does this append command already exist with a different name? If so, what is it called?
Converting my comment to answer so that solution is easy to find for future visitors.
You may use grouping of command using { ...; } to group multiple commands:
{ magic; echo 'taro'; }
And if you want to redirect output to a file then use:
{ magic; echo 'taro'; } > outfile
The best way is not to use a pipe, but anubhava's { magic; echo 'taro'; }.
However, since you asked a pipe, you've opened up Pandora's box of possibilities.
magic|sed '$ataro'
is the first.
magic| awk '{print} END{print "taro"}'
as second.
Or a bash function:
hop(){
while read line; do
echo $line
done
echo $1
}
magic | hop taro
And so on.

Create multiple files in Unix using a script

I am new to unix and I am starting to get my head around it slowly. I would like to know how I can create multiple files within an folder in my directory.
Untill now I was doing it manually one by one. I was using the following code:
echo 'random text here' > newfile1.txt
I would like to create a script that will do the following:
new file x n
newfile1.txt newfile2.txt newfile3.txt newfilen.txt
I would like to have some dummy text inside the files to. I am learning vim and bash.
Thank You
Here is another possibility:
for i in file{1..3}; do printf "random text\n" > $i; done
zsh also allows the more simpler:
printf "random text\n" > random_text{1..3}
One way:
seq 3 | awk '{print "random text" > "newfile"i++".txt"}' i=1
In place of 3, put the value of n.
#!/bin/bash
for n in `seq 1 10`; do
echo "$3" > $1/$2$n.txt
done
This script takes in 3 command line arguments, the first is the already created folder you want the files created in, the second is the first part of the filename, the third is dummy text you want inserted. :)
./script.sh my_folder basename dummytext
(provided as a bash answer)
A classic for loop would be good.
This is just for fun. (don't use in your script)
yes "foo text"|head -10|awk '{print >"newFile"NR".txt"}'
Sometimes we should use yes command, to show that we don't forget him, or he is gonna be sad. :-)

bash one-liner for opening `less` on the last screen w/o temporary files

I try to create a one-liner for opening less on the last screen of an multi-screen output coming from standard input. The reason for this is that I am working on a program that produces a long AST and I need to be able to traverse up and down through it but I would prefer to start at the bottom. I came up with this:
$ python a.py 2>&1 | tee >(lines=+$(( $(wc -l) - $LINES))) | less +$lines
First, I need to compute number of lines in output and subtract $LINES from it so I know what's the uppermost line of the last screen. I will need to reuse a.py output later so I use tee with process substitution for that purpose. As the last step I point less to open an original stdout on a particular line. Of course, it doesn't work in Bash because $lines is not set in last step as every subcommand is run in a subshell. In ZSH, even though pipe commands are not run in a subshell, process substitution still is and therefore it doesn't work neither. It's not a homework or a work task, I just wonder whether it's possible to do what I want without creating a temporary file in Bash or ZSH. Any ideas?
less supports this innately. The + syntax you're using accepts any less command you could enter while it's running, including G for go-to-end.
... | less +G
does exactly what you want.
This is actually mentioned explicitly as an example in the man page (search for "+G").
The real answer to your question should be the option +G to less, but you indicated that the problem definition is not representative for the abstract problem you want to solve. Therefore, please consideer this alternative problem:
python a.py 2>&1 | \
awk '
{a[NR]=$0}
END{
print NR
for (i=1;i<=NR;i++)print a[i]
}
' | {
read -r l
less -j-1 +$l
}
The awk command is printing the number of lines, and then all the lines in sequence. We define the first line to contain some meta information. This is piped to a group of commands delimited by { and }. The first line is consumed by read, which stores it in variable $l. The rest of the lines are taken by less, where this variable can be used. -j-1 is used, so the matched line is at the bottom of the screen.

Output filename from input in bash

I have this script:
#!/bin/bash
FASTQFILES=~/Programs/ncbi-blast-2.2.29+/DB_files/*.fastq
FASTAFILES=~/Programs/ncbi-blast-2.2.29+/DB_files/*.fasta
clear
for file in $FASTQFILES
do cat $FASTQFILES | perl -e '$i=0;while(<>){if(/^\#/&&$i==0){s/^\#/\>/;print;}elsif($i==1){print;$i=-3}$i++;}' > ~/Programs/ncbi-blast-2.2.29+/DB_files/"${FASTQFILES%.*}.fasta"
mv $FASTAFILES ~/Programs/ncbi-blast-2.2.29+/db/
done
I'm trying it to grab the files defined in $FASTQFILES, do the .fastq to .fasta conversion, name the output with the same filename of the input, and move it to a new folder. E.g., ~/./DB_files/HELLO.fastq should give a converted ~/./db/HELLO.fasta
The problem is that the output of the conversion is a properly formatted hidden file called .fasta in the first folder instead of the expected one named HELLO.fasta. So there is nothing to mv. I think I'm messing up in the ${FASTQFILES%.*}.fasta argument but I can't seem to fix it.
I see three problems:
One part of your trouble is that you use cat $FASTQFILES instead of cat $file.
You also need to fix the I/O redirection at the end of that line to > ~/Programs/ncbi-blast-2.2.29+/DB_files/"${file%.fastq}.fasta".
The mv command needs to be executed outside the loop.
In fact, when processing a single file at a time, you don't need to use cat at all (UUOC — Useless Use Of Cat). Simply provide "$file" as an argument to the Perl script.

tee command creates empty file

Hi I have the following list of stocks that is generated and it is placed in file called awk_1
dfs
fsd
dsf
sdf
I then run the following one liner which generates the correct ULR links
while read i ; do
echo $(http://uk.finance.yahoo.com/echartss=$i#symbol=$i\;range=my\;compare=\;indicator=volume\;charttype\=area\;crosshair\=on\;ohlcvalues\=0\;logscale\=off\;source\=undefined\;) tee stock_urls;
done < awk_1
However is does not put the out put in the file called stock_urls ?
Also it generate and strange output on the screen, below is a small section of the output that I get to standard output. It puts "./large_cap_stocks.sh: 51: ./large_cap_stocks.sh:" at the front and "not found" at the end , why might that be happening.
I have searching high and low for why this is not working any help would be really appreciated.
Thanks
You probably meant to write like this:
while read i; do
echo "http://uk.finance.yahoo.com/echarts?s=$i#symbol=$i\;range=my\;compare=\;indicator=volume\;charttype\=area\;crosshair\=on\;ohlcvalues\=0\;logscale\=off\;source\=undefined\;"
done < awk_1 | tee stock_urls
That is:
In the echo command, use "..." to quote your text instead of $(...) which is something else
Use the pipe operator | to pass the output to tee, and you can pipe the entire loop this way, no need to do for individual echo lines.

Resources