What I'm trying to do: I'm passing python file names to my bash script and trying to find all methods. I want to sort them and display them in the following fashion.
function_name file_name:line_number
Where the results are sorted by file_name.
The short version: I'm seeing some unexpected behavior from using += to add elements to my array. It looks like the last grep match from my first file and the first grep match from the second file get stuck together. Can someone help me figure out why?
The long version:
My code:
#!/bin/bash/
for i in $*
do
IFS=','
#result+=($(grep -n -o -P '(?<=def).*(?=\()' $i ) )
result+=( $(grep -n -o -P '(?<=def).*(?=\()' $i | sort -t\: -k2 | tr '\n' ',' | sed 's/.$//') )
unset IFS
done
This the results are:
34: div 39: dot 7: drop 24: minus 19: plus 3: push 15: rot 11: swap 29: times 1: one 7: three 4: two
I want:
34: div 39: dot 7: drop 24: minus 1: one 19: plus 3: push 15: rot 11: swap 29: times 7: three 4: two
After looking at this, I'm guessing the grep only performs the sort on the information passed to it and not on the entire results array. That makes me believe I need to store all the results from the grep in an array, then sort the array based on file name. This is were I am having all sorts (the puns!) of problems.
I've tried:
#!/bin/bash/
for i in $*
do
IFS=','
result+=($(grep -n -o -P '(?<=def).*(?=\()' $i ) )
#result+=( $(grep -n -o -P '(?<=def).*(?=\()' $i | sort -t\: -k2 | tr '\n' ',' | sed 's/.$//') )
unset IFS
done
#echo ${result[*]}
#for a in "${result[*]}"
#do
# echo $a
#done
IFS=','
cheese=($(sort -t\: -k2 <<< "${result[*]}"))
unset IFS
echo ${cheese[*]}
This is much closer, but it looks like the last grep from the first file and first grep from the second file get stuck together. Output from the echo loop:
34: div
39: dot 1: one
7: drop
24: minus
19: plus
3: push
15: rot
11: swap
7: three
29: times
4: two
My output from sorting was correct if the dot and one functions were stuck together:
34: div 39: dot 1: one 7: drop 24: minus 19: plus 3: push 15: rot 11: swap 7: three 29: times 4: two
Input file1:
def push(n):
global stack
stack = [n] + stack
def drop():
global stack
stack.pop(0)
def swap():
global stack
stack[0], stack[1] = stack[1], stack[0]
def rot():
global stack
stack[0], stack[2] = stack[2], stack[0]
def plus():
global stack
num = stack[0] + stack[1]
stack[:2] = [num]
def minus():
global stack
num = stack[1] - stack[0]
stack[:2] = [num]
def times():
global stack
num = stack[0] * stack[1]
stack[:2] = [num]
def div():
global stack
num = stack[1] / stack[0]
stack[:2] = num
def dot():
global stack
print stack.pop(0)
Input file2:
def one():
pass
def two():
pass
def three():
pass
----------UPDATE----------
Here is my final solution. The response below was spot on.
#!/bin/bash
declare -a result
for i in "$@"
do
while read line; # Read the input from the grep command for the current file
do
result+=("${line} $i")
done< <( grep -n -o -P '(?<=def).*(?=\()' ${i})
done
#set up for sorting
IFS=$'\n'
#sort the results into sorted by function name
read -r -d '' -a sorted < <(sort -t: -k2 <<<"${result[*]}" && printf '\0')
unset IFS
#for loop for printing
for a in "${sorted[@]}"; do
#set up delimiter
IFS=' '
#split variable a into array printout
read -ra printout <<< "$a"
#get rid of ":" at the end of the number
num=$(echo "${printout[0]}" | cut -d':' -f 1)
#print in format
printf "%s %s:%s\n" "${printout[1]}" "${printout[2]}" "$num"
done
unset IFS