How to create a command sequence for this?


Recommended Posts

A. Write a command sequence, to create a directory structure like follows:

1. level 1 - 4 directories with random alphanumeric name of 8 characters each directory

2. level 2 - each level 1 directory will have 3 directories - yes, no and yesorno

3. level 3 - each level 3 directory will have 9 directories with directory named in series 1-9 e.g. [1, 2, 3...9]

4. level 4 - each level 4 directory will have 3 directories - yes, no and yesorno

5. all directories at each level will have a text file named abc.txt with random alpha numeric text of 200 characters

Can someone shed a light in a right direction that will help me to achieve this?

Thanks !!

I have a background in C#/VB.NET, so that will influence my answer:

You'll need a few nested For-Next loops to create the exact number of directories you need. You'll also need a pseudo-random number generator to generate the random alphanumeric characters, and to make the "yes, no, or yesorno" directories. The 1-9 directories are easy.

If you're using .NET, use a TextWriter to write the text files.

Have fun!

It could be done in pretty much any language, scripting or otherwise, but assuming you want it in bash:

#!/bin/bash

function random_chars ()
{
	tmp=$( < /dev/urandom tr -dc A-Za-z1-9 | head -c $1 )
	eval $2=$tmp
}

function create_abc ()
{
	local rand=''
	local file=$1'/abc.txt'

	random_chars 200 rand
	echo $rand > $file
	echo $file
}

function create_1to9 ()
{
	for i in 1 2 3 4 5 6 7 8 9
	do

		wd=$1'/'$i
		mkdir $wd
		echo $wd

		create_abc $wd
		create_yesno $wd 0

	done
}

function create_answer ()
{
	local answer=$1'/'$2

	mkdir $answer
	echo $answer

	create_abc $answer  

	if [ $3 == 1 ]
	then
		create_1to9 $answer
	fi
}

function create_yesno ()
{
	create_answer $1 'yes' $2
	create_answer $1 'no'  $2
	create_answer $1 'yesorno' $2
}

function create_dirs ()
{
	local ret=''

	for i in 1 2 3 4
	do
		random_chars 8 ret

		dir=$1'/'$ret
		mkdir $dir
		echo $dir

		create_abc $dir
		create_yesno $dir 1	  

	done

}

function main ()
{
	create_dirs $1
}

main $1

Copy/echo it into a file, chmod +x it.

Then to run:

./script targetdir

targetdir is where you want it to create the directory structure. I just used '.' ( current directory ) for testing.

My bash script knowledge is pretty awful, so I'm sure someone else could do better.

I have a background in C#/VB.NET, so that will influence my answer:

You'll need a few nested For-Next loops to create the exact number of directories you need. You'll also need a pseudo-random number generator to generate the random alphanumeric characters, and to make the "yes, no, or yesorno" directories. The 1-9 directories are easy.

If you're using .NET, use a TextWriter to write the text files.

Have fun!

That's about as efficient as using ice cream for a fire guard ;)

There was a slight bug in random_chars () that caused it to output the abc.txt file incorrectly. Change it to:

Edit: Actually, the tmp variable is superfluous. Just remove it entirely.

function random_chars ()
{
	eval $2=$( < /dev/urandom tr -dc A-Za-z1-9 | head -c $1 )
}

Thanks for your responses.. . .

I came up with following command sequence :::::::::::::


bash$ for i in $(seq 4); do mkdir `< /dev/urandom tr -dc A-Z0-9 | head -c8`; done

bash$ for i in `ls`; do `mkdir -p $i/{yes,no,yesorno}/{1..9} `; done

bash$ find . -type d -exec touch {}/abc.txt \;
[/CODE]

Now I am stuck at creating "yes,no,yesorno" directory in directories with name 1 - 9

This is what I tried ::

bash$ for i in $(find . -type d -name [1-9]); do `mkdir -p /{yes,no,yesorno}`;done

but its prompting with error "permission denied"

What am I missing?

Thanks for your responses.. . .

I came up with following command sequence :::::::::::::


bash$ for i in $(seq 4); do mkdir `< /dev/urandom tr -dc A-Z0-9 | head -c8`; done

bash$ for i in `ls`; do `mkdir -p $i/{yes,no,yesorno}/{1..9} `; done

bash$ find . -type d -exec touch {}/abc.txt \;
[/CODE]

Now I am stuck at creating "yes,no,yesorno" directory in directories with name 1 - 9

This is what I tried ::

bash$ for i in $(find . -type d -name [1-9]); do `mkdir -p /{yes,no,yesorno}`;done

but its prompting with error "permission denied"

What am I missing?

What's happening is you are trying to create the folders /yes, /no, and /yesorno, which are in the [i]root directory[/i] of your filesystem. What you want is to modify that line to be

[CODE]
for i in $(find . -type d -name [1-9]); do `mkdir -p $i/{yes,no,yesorno}`; done
[/CODE]

Basically, you're missing that $i which would make the {yes,no,yesorno} a subdirectory of your random folders as opposed to a subdirectory of the root directory.

  • Like 2

What's happening is you are trying to create the folders /yes, /no, and /yesorno, which are in the root directory of your filesystem. What you want is to modify that line to be


for i in $(find . -type d -name [1-9]); do `mkdir -p $i/{yes,no,yesorno}`; done
[/CODE]

Basically, you're missing that $i which would make the {yes,no,yesorno} a subdirectory of your random folders as opposed to a subdirectory of the root directory.

Thats what I needed. .. . .Thanks.. .

But now there are some other complications I am facing,,, :(

I need to redirect the output to [b]output.txt[/b] and error to [b]error.txt[/b]

[b]I came up with this:[/b]

[CODE]
for i in $(seq 4); do mkdir `< /dev/urandom tr -dc A-Z0-9 | head -c8`<&- 2>$HOME/error.txt; done

for i in `ls` ; do `mkdir -p $i/{yes,no,yesorno}/{1..9}` <&- 1>$HOME/output.txt 2>>$HOME/error.txt; done

for i in $(find . -type d -name [1-9]); do `mkdir -p $i/{yes,no,yesorno} <&- 1>$HOME/output.txt 2>>$HOME/error.txt `;done

for i in $(find . -type d); do `< /dev/urandom tr -dc A-Z0-9 | head -c200 > $i/abc.txt <&- 2>>$HOME/error.txt `; done
[/CODE]

After that, I need to join all the command sequences into one single command.

When I tried joining the commands and placing [b]done [/b]at the end, it seems to be something is missing.. please help

'done' indicates the end of a loop, not the end of a command sequence. 'joining' the command should be as simple as placing them all on one line with semicolons between them. Based on the four commands you quoted in your last post, your final command should look something like this:


for i in $(seq 4); do mkdir `< /dev/urandom tr -dc A-Z0-9 | head -c8`<&- 2>$HOME/error.txt; done; for i in `ls` ; do `mkdir -p $i/{yes,no,yesorno}/{1..9}` <&- 1>$HOME/output.txt 2>>$HOME/error.txt; done; for i in $(find . -type d -name [1-9]); do `mkdir -p $i/{yes,no,yesorno} <&- 1>$HOME/output.txt 2>>$HOME/error.txt `;done; for i in $(find . -type d); do `< /dev/urandom tr -dc A-Z0-9 | head -c200 > $i/abc.txt <&- 2>>$HOME/error.txt `; done
[/CODE]

  • Like 2

'done' indicates the end of a loop, not the end of a command sequence. 'joining' the command should be as simple as placing them all on one line with semicolons between them. Based on the four commands you quoted in your last post, your final command should look something like this:


for i in $(seq 4); do mkdir `< /dev/urandom tr -dc A-Z0-9 | head -c8`<&- 2>$HOME/error.txt; done; for i in `ls` ; do `mkdir -p $i/{yes,no,yesorno}/{1..9}` <&- 1>$HOME/output.txt 2>>$HOME/error.txt; done; for i in $(find . -type d -name [1-9]); do `mkdir -p $i/{yes,no,yesorno} <&- 1>$HOME/output.txt 2>>$HOME/error.txt `;done; for i in $(find . -type d); do `< /dev/urandom tr -dc A-Z0-9 | head -c200 > $i/abc.txt <&- 2>>$HOME/error.txt `; done
[/CODE]

Thank you. . .. Finally. .. :)

[CODE]
for i in $(seq 4); do mkdir `< /dev/urandom tr -dc A-Z0-9 | head -c8`<&- 2>$HOME/error.txt; done;for i in `ls`; do `mkdir -p $i/{yes,no,yesorno}/{1..9}` <&- 1>$HOME/output.txt 2>>$HOME/error.txt; done;for i in $(find . -type d -name [1-9]); do `mkdir -p $i/{yes,no,yesorno}` <&- 1>$HOME/output.txt 2>>$HOME/error.txt; done;for i in $(find . -type d); do `< /dev/urandom tr -dc A-Z0-9 | head -c200 > $i/abc.txt` <&- 2>>$HOME/error.txt; done
[/CODE]

I tried to edit the above post but can't see the edit button, ,, :(

btw, can we redirect the output of mkdir command to a file? i.e output.txt . . .coz its always empty.

And when I execute the command twice, I get an error "Unable to create a directory abc.txt"

How can I make this command to be executed "n" number of times?. . .I don't want to loop it . .. I need to execute the same command on the previous output it generated.

Now I can see the edit button. .

I think your problem is that mkdir doesn't actually output anything to screen unless it encounters an error; so redirecting its output to a file is virtually useless. If you really want it to print a message, try passing it the -v switch. As for the second part of your question about executing the command 'n' times, I have no idea what you are talking about. My best guess is that you want to create a directory inside of a directory that does not yet exist. To create any intermediate directories you could pass mkdir the -p switch. Putting all of the above together your command may look something like the following:


mkdir -pv 'rar' 1>output.txt 2>&1
[/CODE]

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • This is not surprising of course and I stopped using Chrome years ago.
    • It's not that we have to many ads? WTF? LOL
    • I switched to AdGuard for this very reason. All my uBlock filters and user scripts ported over with no issues.
    • This is a hot take, but I only use "New" Outlook for 1 reason, the "My Day" side bar that shows your tasks and Calendar on "New" Outlook allows you to view shared calendars and not just your personal calendar. On "Classic" Outlook it only allows your personal Calendar. For my job, we have a group shared Calendar that shows appointments and scheduled tasks for the team and we don't really use our personal calendars.  
    • Opera for Android gets redesigned home page with FIFA World Cup tracker by Taras Buria FIFA World Cup 2026 is kicking off in the United States later this week, and Opera, a popular cross-platform browser, is making it easier to track matches on mobile. Today, Opera announced a redesigned home page for its Android browser. The new home page is now "more immersive" with easier access to common browser features. Users can now customize Speed Dial icons (round, square, or squircle), enjoy a new weather widget with real-time conditions, and open AI Mode or a private session with a single tap. Additionally, the browser now has a built-in football tracker, allowing you to follow your favorite team without using dedicated apps. The tracker displays live scores, notifications, and statistics in a dedicated football hub. You can also check out line-ups, match events, and more. Opera surveyed its users, and 38% of responders said they plan to follow the FIFA World Cup 2026 in a browser. The tournament starts on June 11 and ends on July 19, 2026. "By providing football fans with instant access to live scores alongside a more considered design, we’re ensuring they are never more than a tap away from the action, even when they can't watch live," said Tim Lesnik, Product Manager at Opera Mobile. For Opera users in the United States, Opera runs a contest, offering them a chance to win tickets to a match in Miami in July, Android smartphones, PlayStation 5 consoles, smart TVs, and Amazon Vouchers. Users can participate by posting on social media with the #OperaFandom hashtag from June 12 or by signing up on the official Opera website. Opera will announce winners on July 3. You can download Opera for Android from the Google Play Store using this link.
  • Recent Achievements

    • Week One Done
      skylerssviv earned a badge
      Week One Done
    • One Month Later
      mobmobiles earned a badge
      One Month Later
    • Very Popular
      Captain_Eric earned a badge
      Very Popular
    • One Month Later
      amusc earned a badge
      One Month Later
    • One Month Later
      DJC50PLUS earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      506
    2. 2
      PsYcHoKiLLa
      227
    3. 3
      +Edouard
      96
    4. 4
      ATLien_0
      92
    5. 5
      Steven P.
      82
  • Tell a friend

    Love Neowin? Tell a friend!