I'm trying to create a script that goes line by line in a file, extracts the last word in each sentence and performs another script I created (which works, called intermediate) and prints all of that as separate lines.

For some reason I get an endless loop.

function find_id {
  temp_file="`echo $next_file | cut -d"." -f1`"
  if [[ $temp_file != station ]]; then
      while read line; do
          if [[ -f "${temp_file}.station" ]]; then
              $train_id=`echo ${line[${train_col}]}`
              echo -n "`intermediate $train_id`"
      done < ${temp_file}.station
      next_file="`echo $next_file | cut -d"." -f2- | cut -d" " -f2-`"
      temp_file="`echo $next_file | cut -d"." -f1`"
      echo "`find_id $1 $next_file`"


file_list= `ls *.station``
echo "`find_id $1 $file_list``" | sort -n | cut -d" " -f2- | uniq

I'm not allowed to use awk or sed.


2 Answers 2


With the activity you are doing as explained in your question seems you only need an awk for those all things instead.

awk '$NF' infile*.txt > outfile.txt

The $NF is referring to the last word (means a word with whitespaces around) in each line in awk.

While the above awk solution is there, you can use can read the lines to an array and print last element of that array with negative index (bash 4.3 and above).

arrayedline=( $line ) 
printf "%s\n", "${arrayedline[@]-1}"

In older version of bash your can use expression in index arrayedline[${#arrayedline[@]-1}], which with substring one from the length of array ${#arrayedline[@]} we can get last element of that.

arrayedline=( $line )
printf "%s\n", "${arrayedline[${#arrayedline[@]}-1]}" 

Or you can even use as follows :

printf "%s\n", "${arrayedline[@]:(-1)}"  #or
printf "%s\n", "${arrayedlne[@]: -1}"

Now that in bash array index is starting from 0.

  • And if I have to work around not being able to use awk or $NF? Commented Aug 22, 2017 at 19:47
  • @evgniytayarov What Unix without awk are you using?
    – Kusalananda
    Commented Aug 22, 2017 at 20:35
  • @evgniytayarov Answer updated. Commented Aug 23, 2017 at 3:40

Here is how you can do it with the additional requirement that you cannot use sed either:

for i in `split -n 1 fn* --filter='cat | rev | cut -f 1 -d 'f' | rev'`; do ./yourscript.sh $i; done

Explanation of why it works:

split splits the files whose filename starts with fn into lines, and processes cat | rev | cut -f 1 -d ' ' | rev on each line.

cat echoes that line, rev reverses it, cut separates it into words delimited by ' ' and outputs the first word of the reversed string, rev reverses it back; you get the last word of your line.

Then the for...do...done executes your script on that word.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .