I have a file called export_list that has 8 values on separate lines. I am looking to make another file, that echoes the values. For some reason I cannot find the write expression to increment the line value of sed. Any help is appreciated.
export_list looks like this:
1
2
3
4
5
6
7
8
I have an import file that looks like this:
count=1
if [ $count -lt 8 ]
then
value=$(sed -n ''$count'p' < export_list)
echo $value
((count++))
fi
I think you need to look at read:
count=0
while read value
do
echo $value
((count++))
done < export_list
This looks a lot simpler to me. Note that the redirection does have to be after the done. There are also reasons in Bash not to try cat export_list | while read value; do … done.
You can use awk like this command awk '{print $0+1}' export_list
[root#~ ] # awk '{print $0+1}' export_list
2
3
4
5
6
7
8
9
Related
I need a bash script to find the sum of the absolute value of integers separated by spaces. For instance, if the input is:
1 2 -3
the script should print 6 to standard output
I have:
while read x ; do echo $(( ${x// /+} )) ; done
which gives me
0
Without over complicated things, how would I include an absolute value of each x in that statement so the output would be:
6
With Barmar's idea:
echo "1 2 -3" | tr -d - | tr ' ' '+' | bc -l
Output:
6
You have almost done it, but the -s must have been removed from the line read:
while read x; do x=${x//-}; echo $(( ${x// /+} )); done
POSIX friendly implementation without running a loop and without spawning a sub-shell:
#!/usr/bin/env sh
abssum() {
IFS='-'
set -- $*
IFS=' '
set -- $*
IFS=+
printf %d\\n $(($*))
}
abssum 1 2 -3
Result:
6
I have a list of shell scripts (that end with .sh) in a folder and I am trying to make a list of them, and the list should have two script names (separated by a space) in each line. I wrote the following script, but it does not work without showing any errors. I was hoping to get some help here:
file1=""
for file in $(ls ./*.sh); do
i=1
file1="$file1$file "
if [ $i -lt 3 ]; then
i=$(( i++ ))
continue
fi
echo "file1 is $file1" # expected $file1 is: scriptName1.sh scriptName2.sh
echo $file1 >> ScriptList.txt # save the two file names in the text file
file1=""
done
To get tab separated output:
ls *.sh | paste - -
The pr utility is handy for columnizing as well. It can split the data "vertically":
$ seq 10 | pr -2 -T -s" "
1 6
2 7
3 8
4 9
5 10
or "horizontally"
$ seq 10 | pr -2 -T -s" " -a
1 2
3 4
5 6
7 8
9 10
It's not a good idea to set i=1 everytime in your loop.
Try
ls -1 | while read a;
do
if [ -z $save ]; then
save="$a"
else
echo "$save $a"
save=""
fi
done
I wonder If it is possible to write "for i in {n..k}" loop with a variable.
For example;
for i in {1..5}; do
echo $i
done
This outputs
1
2
3
4
5
On the other hands
var=5
for i in {1..$var}; do
echo $i
done
prints
{1..5}
How can I make second code run as same as first one?
p.s. I know there is lots of way to create a loop by using a variable but I wanted to ask specifically about this syntax.
It is not possible to use variables in the {N..M} syntax. Instead, what you can do is use seq:
$ var=5
$ for i in $(seq 1 $var) ; do echo "$i"; done
1
2
3
4
5
Or...
$ start=3
$ end=8
$ for i in $(seq $start $end) ; do echo $i; done
3
4
5
6
7
8
While seq is fine, it can cause problems if the value of $var is very large, as the entire list of values needs to be generated, which can cause problems if the resulting command line is too long. bash also has a C-style for loop which doesn't explicitly generate the list:
for ((i=1; i<=$var; i++)); do
echo "$i"
done
(This applies to constant sequences as well, since {1..10000000} would also generate a very large list which could overflow the command line.)
You can use eval for this:
$ num=5
$ for i in $(eval echo {1..$num}); do echo $i; done
1
2
3
4
5
Please read drawbacks of eval before using.
I have a file with many lines, like
1 jfkdajfd 1 2 3 5
2 fkldfjld
3 fdkfloaf 9 10
4 fldfldkf
5 fdskf;ak 12 1 4
I want to get all the numbers and put them in a column in a file, like
1
2
3
5
9
10
12
1
4
how can I achieve this?
thanks
In your case, it looks like you can do this:
awk '{for (i=3;i<=NF;++i) {print $i}}'
This is assuming that all the numbers you want to print occur in column 3 or after.
cat file | while read line
do
for i in $(echo ${line})
do
isnumeric=$(echo ${i} | grep -q [0-9]; echo ${?})
if [ ${isnumeric} -eq 0 ]
then
echo ${i} >> outfile
fi
done
done
not bulletproof and not as elegant as the previously given solutions, but it shows what is being used for determining if this is a numeric or not.
while read num alpha rest; do
[[ "$rest" ]] && printf "%s\n" $rest # <-- variable is unquoted
done < filename
I want to write a loop in Bourne shell which iterates a specific set of numbers. Normally I would use seq:
for i in `seq 1 10 15 20`
#do stuff
loop
But seemingly on this Solaris box seq does not exist. Can anyone help by providing another solution to iterating a list of numbers?
try
for i in 1 10 15 20
do
echo "do something with $i"
done
else if you have recent Solaris, there is bash 3 at least. for example this give range from 1 to 10 and 15 to 20
for i in {1..10} {15..20}
do
echo "$i"
done
OR use tool like nawk
for i in `nawk 'BEGIN{ for(i=1;i<=10;i++) print i}'`
do
echo $i
done
OR even the while loop
while [ "$s" -lt 10 ]; do s=`echo $s+1|bc`; echo $s; done
You can emulate seq with dc:
For instance:
seq 0 5 120
is rewritten as:
dc -e '0 5 120 1+stsisb[pli+dlt>a]salblax'
Another variation using bc:
for i in $(echo "for (i=0;i<=3;i++) i"|bc); do echo "$i"; done
For the Bourne shell, you'll probably have to use backticks, but avoid them if you can:
for i in `echo "for (i=0;i<=3;i++) i"|bc`; do echo "$i"; done
#!/bin/sh
for i in $(seq 1 10); do
echo $i
done
I find that this works, albeit ugly as sin:
for i in `echo X \n Y \n Z ` ...
for i in `seq 1 5 20`; do echo $i; done
Result:
5
10
15
20
$ man seq
SEQ(1) User Commands SEQ(1)
NAME
seq - print a sequence of numbers
SYNOPSIS
seq [OPTION]... LAST
seq [OPTION]... FIRST LAST
seq [OPTION]... FIRST INCREMENT LAST