Bash Scripting note running - bash

Given an array of string element, join all the elements of the array with spaces, convert all letters to lowercase and send the result to stdout.
Also have challenges with this "Given an array of strings, count the strings that contain at least one uppercase character and output the result to stdout."
Please any heads-up will be appreciated!
I wrote this for question 1:
#!/bin/bash
var=$(IFS='\n'; echo "$(my_array[*])")
var=$(IFS=''; echo "$((${my_arrary[#]}))")
echo $var | tr '[:upper:]' '[:lower]'
echo "$var" | awk '{print tolower($#)}')
echo result
exit 0
But got error when I ran into error as shown below:
$ bash script.sh
script.sh: line 2: my_array[*]: command not found
0
script.sh: line 6: syntax error near unexpected token `)'
script.sh: line 6: `echo "$var" | awk '{print tolower($#)}')'

Related

How to parse multiple line output as separate variables

I'm relatively new to bash scripting and I would like someone to explain this properly, thank you. Here is my code:
#! /bin/bash
echo "first arg: $1"
echo "first arg: $2"
var="$( grep -rnw $1 -e $2 | cut -d ":" -f1 )"
var2=$( grep -rnw $1 -e $2 | cut -d ":" -f1 | awk '{print substr($0,length,1)}')
echo "$var"
echo "$var2"
The problem I have is with the output, the script I'm trying to write is a c++ function searcher, so upon launching my script I have 2 arguments, one for the directory and the second one as the function name. This is how my output looks like:
first arg: Projekt
first arg: iseven
Projekt/AX/include/ax.h
Projekt/AX/src/ax.cpp
h
p
Now my question is: how do can I save the line by line output as a variable, so that later on I can use var as a path, or to use var2 as a character to compare. My plan was to use IF() statements to determine the type, idea: IF(last_char == p){echo:"something"}What I've tried was this question: Capturing multiple line output into a Bash variable and then giving it an array. So my code looked like: "${var[0]}". Please explain how can I use my line output later on, as variables.
I'd use readarray to populate an array variable just in case there's spaces in your command's output that shouldn't be used as field separators that would end up messing up foo=( ... ). And you can use shell parameter expansion substring syntax to get the last character of a variable; no need for that awk bit in your var2:
#!/usr/bin/env bash
readarray -t lines < <(printf "%s\n" "Projekt/AX/include/ax.h" "Projekt/AX/src/ax.cpp")
for line in "${lines[#]}"; do
printf "%s\n%s\n" "$line" "${line: -1}" # Note the space before the -1
done
will display
Projekt/AX/include/ax.h
h
Projekt/AX/src/ax.cpp
p

Why am I getting a syntax error in this bash command on parentheses printf and calculator function?

Why am I getting an error with the ( in this line of script?
printf "%.3f\n" "$(bc -l <<< ($sum / $total))"
Error:
solution.sh: command substitution: line 11: syntax error near unexpected token `('
solution.sh: command substitution: line 11: `bc -l <<< ($sum / $total))"'
The desired behavior is to take a numerical variables $sum and $total and perform division on them, then print out the value to 3 decimal points.
It is because bc -l needs input as a single string but ($sum / $total) is unquoted and gets split into more than one word.
You may use:
printf "%.3f\n" "$(bc -l <<< "($sum / $total)")"
Better do it like below. It would be more clear
result=$(bc -l <<< ($sum / $total))
printf "%.3f\n" "$result"

Find special character in last line of text file

I have a text file like this (e.g., a.txt):
1.1.t
1.2.m
If the last line consists of the character m, I want to echo Ok.
I tried this:
line=` awk '/./{line=$0} END{print line}' a.txt`
line1= `echo $line | grep "m"`
if [[ $line1= `:` ]] ; then
echo
else
echo "Ok"
fi
It does not work, and the error is:
bash: conditional binary operator expected
bash: syntax error near ``:`,
`if [[ $line1= `:` ]] ; then'
if [[ $line1=:]] is incorrect syntax in couple of ways as spaces around = are missing and backtick is used for command substitution
awk itself can handle this:
awk '/./{line=$0} END{print (line ~ /\.m/)? "ok" : "no"}' file
ok
You could also use tail and grep:
[[ -n $(tail -1 a.txt | grep "m$") ]] && echo "OK" || echo "FAILED"
You can use sed:
sed -n '${/m$/s/.*/OK/p;}' file
The option -n suppresses output by default. $ addresses the last line of input. In that case we check if the line ends with m through /m$/. If that is the case we substitute the line with the word OK and print it.
Btw, I was going trough your shell script, there are really too many errors to explain, the syntax error is because there is no space between $line1 and the = in the [[ ... ]] conditional. But hey, this is far from being the only problem with that script. ;)
http://www.shellcheck.net/ might be a good resource to enhance your scripts.

if conditional in bash giving error

I have a small bash script where I want to get the format of a file.
FILENAME=$1
GET_FILE_FORMAT=`file $FILENAME | grep -i data`
if[[ "$GET_FILE_FORMAT" = *data* ]]
echo "Format Data";
fi
However the output that I get is as follows
./try.bash test.data
./try.bash: line 4: if[[ test.data : data = *data* ]]: No such file or directory
Format Data
./try.bash: line 6: syntax error near unexpected token `fi'
./try.bash: line 6: `fi'
There are a couple of problems here:
You don't have any space after if.
The end of the conditional, i.e. if, isn't indicated.
To fix, say:
if [[ "$GET_FILE_FORMAT" = *data* ]]; then
To prevent getting incorrect information when the file name itself contains the string data, say:
GET_FILE_FORMAT=$(file "${FILENAME}" | awk -F: '{print $NF}')

BASH - Reading Multiple Lines from Text File

i am trying to read a text file, say file.txt and it contains multiple lines.
say the output of file.txt is
$ cat file.txt
this is line 1
this is line 2
this is line 3
I want to store the entire output as a variable say, $text.
When the variable $text is echoed, the expected output is:
this is line 1 this is line 2 this is line 3
my code is as follows
while read line
do
test="${LINE}"
done < file.txt
echo $test
the output i get is always only the last line. Is there a way to concatenate the multiple lines in file.txt as one long string?
You can translate the \n(newline) to (space):
$ text=$(tr '\n' ' ' <file.txt)
$ echo $text
this is line 1 this is line 2 this is line 3
If lines ends with \r\n, you can do this:
$ text=$(tr -d '\r' <file.txt | tr '\n' ' ')
Another one:
line=$(< file.txt)
line=${line//$'\n'/ }
test=$(cat file.txt | xargs)
echo $test
You have to append the content of the next line to your variable:
while read line
do
test="${test} ${LINE}"
done < file.txt
echo $test
Resp. even simpler you could simply read the full file at once into the variable:
test=$(cat file.txt)
resp.
test=$(tr "\n" " " < file.txt)
If you would want to keep the newlines it would be as simple as:
test=<file.txt
I believe it's the simplest method:
text=$(echo $(cat FILE))
But it doesn't preserve multiple spaces/tabs between words.
Use arrays
#!/bin/bash
while read line
do
a=( "${a[#]}" "$line" )
done < file.txt
echo -n "${a[#]}"
output:
this is line 1 this is line 2 this is line 3
See e.g. tldp section on arrays

Resources