0

I have 10 folders with consecutives name : book_1, book_2..... book_10 and each folder has a txt file named same as the folder. For example : book_1 has only book_1.txt and contains history material (only text).

I need to run an AWK script which output should be added by order to the output file. How can I generate a loop which runs through my folders and extractes the needed file from each folder?

awk '
    {
        script//
    }
    END { print "The output of book num $i is:  " m }' book*/book*.txt >> output.txt // m is a variable which extracts max occurences of certain words which are set in the script

My output should look like this:

The output of book num 1 is : 123
The output of book num 2 is : 2223

and so on

thank you for your help!

12
  • 1
    Awk is a mighty tool for text transformation, not for handling files. You are looking for a combination of find and cat. Hint: There a dozens of simple ways to achieve it. Commented Mar 31, 2020 at 17:48
  • Please show the contents of at least one example file book_1/book_1.txt (or better two files) in your question and explain where the numbers 123 and 2223 come from if it's not obvious.
    – Bodo
    Commented Mar 31, 2020 at 17:52
  • Added some description. Each book has some reading material in different subject. the output displays max occurences of certain words
    – yelena
    Commented Mar 31, 2020 at 18:02
  • awk doesn't really know how to open directories. The solution to your problem may be just to call it with the right arguments, eg. awk '...' book_?/book_?.txt book_??/book_??.txt which will rely on the shell globbing to expand the file arguments in the right order.
    – user313992
    Commented Mar 31, 2020 at 18:11
  • Within awk, you can check if it's the beginning of a new file with FILENAME==fn { fn = FILENAME; ... } or via the FNR variable. GNU awk also has BEGINFILE and ENDFILE similar to BEGIN and END.
    – user313992
    Commented Mar 31, 2020 at 18:13

1 Answer 1

0

The simple way using any awk in a shell that supports the {1..10} construct for generating a range of numbers (otherwise just use $(seq 10)) is:

for i in {1..10}; do
    awk -v i="$i" '
        {
            script//
        }
        END { printf "The output of book num %d is : %d\n", i, m }
    ' "book_${i}/book_${i}.txt"
done > output.txt

but if you really wanted to do it all in awk it'd be (using GNU awk for ARGIND and ENDFILE):

awk '
    BEGIN {
        for (i=1; i<=10; i++) {
            ARGV[ARGC] = "book_" i "/book_" i ".txt"
            ARGC++
        }
    }
    {
        script//
    }
    ENDFILE { printf "The output of book num %d is : %d\n", ARGIND, m; m=0 }
'  > output.txt

If any of the "book" files can not exist then you'd need to add some protection against that.

3
  • I used your first script, and it almost did the job. however for some reason the output numbering was out of order and didn't include all of the numbers in the range (I tried using both methods {1..10} and $(seq 10) but got same result. Only the the number order is oncorrect, the output by itself corresponds to it's true number (by line count). For example : The output of book num 4 is 123 // output matches book 1 The output of book num 1 is 234 //output matches book 2 The output of book num 4 is 333 //output matches book 3
    – yelena
    Commented Apr 1, 2020 at 15:52
  • I can't imagine how {1..10} or seq 10 could produce output that's not the numbers 1 through 10 in that order. You must not be doing exactly what I show in my script. Please edit your question to show a complete, minimal script that demonstrates your problem.
    – Ed Morton
    Commented Apr 1, 2020 at 16:56
  • 1
    I looked through my script again and found a variable named "i" which led to false indexing. Again thank you!
    – yelena
    Commented Apr 1, 2020 at 18:45

You must log in to answer this question.

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