0

I am learning for an approaching exam and I've been learning more and more about bash.
One of the question goes as follows:
- Get at least 11 arguments (else, give an stderr output and exit)
- The first argument is going to be a directory
- The other arguments shall become .txt files in that directory

I can't seem to figure out how to create an N amout of text files ( N=number of arguments).

I have already tried a for loop like in the shown code, but i cannot seem to really figure it out. I should mention that this is shell is being ran in a Linux Subsystem on Windows 10 ( if it's in any way important ).

#!/bin/bash

count=$#
if [ $# -lt 11 ]
then
    >&2 echo "Didn't receive enough arguments."
    exit 1 
fi

if [ ! -r $1 ]
then
    echo "Creating file..."
    mkdir $1
    echo "...done."
fi

cd $1

for i in {1..$count}
do
    echo $i
    echo >> $i.txt
done

The output should be simple, a directory with the name of $1, in it, N amout of text files. Something similar to this:
-$2.txt
-$3.txt
-$4.txt
.
.
.
-$N.txt

Baş Denis
  • 21
  • 2
  • `touch file{1..10}` will create `file1, file2, file3, ... file10` in the current directory. (or `touch file{1..10}.txt` to add the `.txt` extension) And... you really don't want `'$'` as part of the filename. – David C. Rankin Aug 28 '19 at 08:43
  • The problem is still here. I get an unknown amount of arguments, so i would be inclined to do touch file{1..$#}.txt . But all it does is to create a file called file{1..11}.txt (if given 11 arguments). – Baş Denis Aug 28 '19 at 08:50
  • You cannot use a variable inside the brace expansion `{1..}` without using `eval`. You can loop `for ((i=0; i < $#; i++)); do touch file$i.txt; done` – David C. Rankin Aug 28 '19 at 08:53

2 Answers2

0

The following

#!/bin/bash

count=5

for i in {0..5}
do
echo $i
done

will output:

1
2
3
4
5

and the following

for i in {0..$count}
do
echo $i
done

will output:

{1..5}

The reason for this is the order in which things occur in bash. Brace expansion occurs before variables are expanded.

So, you should change your for loop for the solution to work. A solution using seq like the following will make your script work.

for i in $(seq 1 $count)
do
    echo "$i"
    echo >> $i.txt
done

You can also use a c style for loop

for ((i=0; i<=count; i++));

There are many other ways. Please see the below references for more: Reference1 Reference 2

j23
  • 3,139
  • 1
  • 6
  • 13
0

I'm not clear why files are named 1.txt, 2.txt, .... To me, The other arguments shall become .txt files in that directory sounds like the files should be named according to the respective argument. That can be done in a loop like so:

    #! /bin/sh

    if [ $# -lt 11 ]
    then
        >&2 echo "Didn't receive enough arguments."
        exit 1 
    fi

    # errors given
    mkdir "$1" && cd "$1" || exit 1

    while [ $# -ge 2 ]; do
        shift
        touch "$1.txt"
    done

Ale
  • 887
  • 10
  • 14
  • Yeah, I realized my mistake a few hours after I have posted the question. I have modified the code like this so I can create a .txt file with whatever name I get. Thanks for the response! – Baş Denis Aug 30 '19 at 11:02