How to get specific words by index in a line bash - bash

I have a script that takes parameters such as:
script.sh 1 3
I want to then go through a text file and print out the first and third words from each line. I have simply no idea how to do this. If anyone could help I'd really appreciate it...
This is what I currently have:
counter=0
wordcounter=0
param=$(echo "$3" | tr , " ")
words(){
for word in $1; do
for col in $param; do
if [ $wordcounter -eq $col ]; then
echo $word
fi
done
done
wordcounter=$((wordcounter + 1))
}
eachline() {
newline=$(echo "$1" | tr , " ")
for word in $newline; do
if [ $counter -gt 3 ]; then
echo "$word"
fi
counter=$((counter + 1))
done
if [ $counter -gt 0 ]; then
words "$newline"
fi
counter=$((counter + 1))
}
while read line; do
eachline $line
done < company/employee.txt

Use awk:
$ awk '{print $1 " " $3}' file
for file:
1 2 3 4 5
6 7 8 9 0
Output is:
1 3
6 8
In bash script:
#!/bin/bash
awk_command="{print";
for i in "$#"; do
awk_command="${awk_command} \$${i} \" \"";
done
awk_command="${awk_command}}";
awk "$awk_command" file
With this script you can pass any number of indexes:
For 1 and 2:
$ ./script.sh 1 2
1 2
6 7
For 1, 2 and 5:
$ ./script.sh 1 2 5
1 2 5
6 7 0

Related

numbers as command-line arguments and prints the count

I want to take numbers as command-line arguments and prints the count of
numbers that end with 0, 1, 2, etc. up to 5.
Example:
bash test.sh 12 14 12 15 14
Expected Output:
Digit_ends_with count
0 0
1 0
2 2
3 0
4 2
5 1
Mt Attempt:
read -a integers for i in ${integers[#]} do if [[ grep -o '[0-9]' $i ]] count=$(grep -c $i) if [ "$count" -ge "0" ] then
echo "Digit_ends_with" $i echo -e "Count ""$count" fi fi done
But this is not working. How I can achieve this requirement?
#!/bin/bash
echo "Digit_ends_with count" #print table header
for argument in "$#" #loop over all given arguments
do
current=$(echo "$argument" | tail -c 2 ) #get last digit
if (( "$current" <= 5 )) #check if lower than 6
then
echo "$current" #echo if true
fi
done | sort | uniq -c | sed -E 's/\s+//' | sed -E 's/([0-9]+).?([0-9]+)/\2\t\t\1/' #sort, count, remove leading spaces and switch the fields
Example:
╰─$ ./test.sh 188 182 182 12 13 14 18 15 16 17 18 19 10 0 0 0 0 0 0 0 0 0 0
Digit_ends_with count
0 11
2 3
3 1
4 1
5 1
Would you please try the following:
#!/bin/bash
for i in "$#"; do # loop over arguments
(( count[i % 10]++ )) # index with the modulo 10
done
printf "%s %s\n" "Digit_ends_with" "count" # header line
for (( i = 0; i < 6; i++ )); do # loop between 0 and 5
printf "%d\t\t%d\n" "$i" "${count[$i]}" # print the counts
done
Result of ./test.sh 12 14 12 15 14:
Digit_ends_with count
0 0
1 0
2 2
3 0
4 2
5 1

Issue with program check if the number is divisible by 2 with no remainder BASH

I tried to write a program to see if the count divisible by 2 without a remainder
Here is my program
count=$((count+0))
while read line; do
if [ $count%2==0 ]; then
printf "%x\n" "$line" >> file2.txt
else
printf "%x\n" "$line" >> file1.txt
fi
count=$((count+1))
done < merge.bmp
This program doesnt work its every time enter to the true
In the shell, the [ command does different things depending on how many arguments you give it. See https://www.gnu.org/software/bash/manual/bashref.html#index-test
With this:
[ $count%2==0 ]
you give [ a single argument (not counting the trailing ]), and in that case, if the argument is not empty then the exit status is success (i.e. "true"). This is equivalent to [ -n "${count}%2==0" ]
You want
if [ "$(( $count % 2 ))" -eq 0 ]; then
or, if you're using bash
if (( count % 2 == 0 )); then
Some more "exotic" way to do this:
count=0
files=(file1 file2 file3)
num=${#files[#]}
while IFS= read -r line; do
printf '%s\n' "$line" >> "${files[count++ % num]}"
done < input_file
This will put 1st line to file1, 2nd line to file2, 3rd line to file3, 4th line to file1 and so on.
awk to the rescue!
what you're trying to do is a one-liner
$ seq 10 | awk '{print > (NR%2?"file1":"file2")}'
==> file1 <==
1
3
5
7
9
==> file2 <==
2
4
6
8
10
try
count=$((count+0))
while read line; do
if [ $(($count % 2)) == 0 ]; then
printf "%x\n" "$line" >> file2.txt
else
printf "%x\n" "$line" >> file1.txt
fi
count=$((count+1))
done < merge.bmp
You have to use the $(( )) around a mod operator as well.
How to use mod operator in bash?
This will print "even number":
count=2;
if [ $(($count % 2)) == 0 ]; then
printf "even number";
else
printf "odd number";
fi
This will print "odd number":
count=3;
if [ $(($count % 2)) == 0 ]; then
printf "even number";
else
printf "odd number";
fi

Bash: While loop-Error " No such file or directory" [duplicate]

This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 6 years ago.
I have some code that doesn't work. It's says, "No such file or directory", and crashes on line 27:
while [ $i < $amount]
But I don't know why. Anyone?
#!/bin/bash
#WWGEN Aleandro
small=$(echo "abcdefghijklmnopqrstuvwxyz")
big=$(echo "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
C=$(echo "\"")
D=$(echo '!')
E=$(echo ",.##$%^&*()][{};:?-_+=")
F=$(echo "0123456789")
characters=$(echo $small$big$C$D$E$F)
while getopts ":cl:p:" opt; do
case "$opt" in
c) characters=$(echo $big$C$D$E$F);;
l) length=$OPTARG ;;
p) amount=$OPTARG ;;
esac
done
shift $(( OPTIND - 1 ))
i=0
echo "amount: $amount"
echo "length: $length"
while [ $i < $amount]
do
echo "test"
echo $characters | sed 's/\(.\)/\1\n/g ' | sed 's/^$//g'| shuf -n $length | paste -sd ''
i=$[$i+1]
done
Output:
bash wwgen.sh -l 6 -p 5
amount: 5
length: 6
wwgen.sh: line 27: [: 0: binary operator expected
Wanted Output:
5 random generated passwords with length of 6 like this.
bash wwgen.sh -l 6 -p 5
amount: 5
length: 6
69:AY
O7H;=
64]Z
]^NL!
(&NW5
while [ $i < $aantal ]
tries to do some stuff involving taking input from file $aantal which explains the message.
For inferior test use:
while [ $i -lt $aantal ]
Simple example to prove my point:
#!/bin/bash
i=0
a=2
while [ $i -lt $a ]
do
i=$[i+1]
echo $i
done
output:
1
2
However, if I don't define a I get:
./test.sh: ligne 3 : [: 0 : opérateur unaire attendu
(I'll let you perform the translation from french :))

Converting from for loop to while if fi loop UNIX

I'm trying to figure out how to convert the following for loop into a while loop or until loop including if fi for UNIX Here's the code...
#!/bin/bash
if [ $# -gt 0 ] ; then
start=$1
end=$3
step=$2
for x in `seq $start $step $end` ; do
number $x
done
else
echo Enter at least one number on the command line.
fi
Any help is greatly appreciated!
(( x = start ))
until (( x > end ))
do
number $x
(( x += step ))
done
For a loop like this, it's easiest to use the numeric-style for loop:
for ((x=start; x<=end; x+=step)); do
number $x
done
Using seq is good as it has some default values for step and end value. I added this to the if if only one, or two arguments are given. Also it handles the situation if the given argument are not numbers (default values are 0). Also an endless loop may encounter if step is zero. If You remove this checking it will work the same way as the seq version.
if [ $# -gt 0 ] ; then
x=$(($1+0))
end=$((${3:-$x}+0))
step=$((${2:-1}+0))
[ $step -eq 0 ] && echo "Step is zero!" && exit 1
while [ $x -le $end -a $step -gt 0 -o $x -ge $end -a $step -lt 0 ]; do
echo $x
x=$((x+step))
done
else
echo Enter at least one number on the command line.
fi
Change echo to number in the while loop if you would like to use!
Examples:
$ ./e.sh 1
1
$ seq 1
1
$ ./e.sh 1 1 3
1
2
3
$ seq 1 1 3
1
2
3
$ ./e.sh 1 -1 3
$ seq 1 -1 3
$ ./e.sh 3 -1 1
3
2
1
$ seq 3 -1 1
3
2
1
$ ./e.sh 1 0 1
Step is zero!
$ seq 1 0 1|head
1
1
1
... (endlessly)
$ ./e.sh 1 .1 1.2
./e.sh: line 3: 1.2+0: syntax error: invalid arithmetic operator (error token is ".2+0")
$ seq 1 .1 1.2
1.0
1.1
1.2
Bash arithmetic is not working with floating point numbers, but seq does. If You need this feature You could use the x=$(echo $x + $step|bc) format. Also $((...)) should replaced by $(...|bc) like lines.
In Bash 4 you can also do it like this:
for i in {$start..$stop..$step}; do
echo $i
done

check if the argument is a number inside the shell script [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I test if a variable is a number in bash?
I try writing the fibonacci sequence by shell scripting for example if user entered 5 after the script name in the command line the script needs to print out the 5 fibonacci numbers from the beginning which are:
0 1 1 2 3
I have completed the script but I need to check the user input if it is positive number that I have a problem in this part.
in the command line the user should call the script and then enter a positive number
./script number
and this is my code:
#!/bin/sh
[ $# -ne 1 ] && { echo "enter a number please" ; exit 1 ; }
[ ! echo $1 | egrep -q '^[0-9]+$' && $1 -lt 0 ] && { echo "negative" ; exit 1 ; }
f0=0
f1=1
counter=2
if [ $1 -eq 0 ] ; then
echo -n "0"
elif [ $1 -ge 1 ] ; then
echo -n "0 1"
fi
while [ $counter -le $1 ] && [ $1 -gt 1 ] ; do
echo -n "$fn "
fn=`expr $f0 + $f1`
f0=$f1
f1=$fn
counter=`expr $counter + 1`
done
echo ""
if [ $1 -ge 0 2>/dev/null ] ; then
it works for positive numbers equal or greater than 0
Take a look at this:
http://www.bashguru.com/2010/12/how-to-validate-integer-input-using.html
Apparently someone wrote multiple shell scripts to do exactly that.

Resources