1

I want to generate a random existing path to cd and write file in it, if possible random from a specified root (the point is that can be used like cd /home/foobar/$RANDOM).

I think I can do this by listing all paths with ls and awk with this command, according to ls command: how can I get a recursive full-path listing, one line per file?

ls -R /path | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'

And giving result line per line to $(dirname "${LINE_FILE}") and finishing by purging dupes.

It should work but I need generate a lot of random existing paths and I hope a quicker solution exist (this generation may take a lot of time, worky but dirty). Any better ideas?

Glastis
  • 163
  • 4
  • 15

3 Answers3

2

Another variant with find + sort -R:

startDir='/your/path'
maxPathRange=10
endPath=$startDir

for (( i=1; i<=$((1 + RANDOM % $maxPathRange)); i++ )); do
    directory=$(find "$endPath" -maxdepth 1 -type d ! -path "$endPath" -printf "%f\n" | sort -R | head -n 1) 
    if [[ -z $directory ]]; then break; fi
    endPath=$endPath/$directory
done <<< "$directory"

cd "$endPath" && pwd
tripleee
  • 175,061
  • 34
  • 275
  • 318
beliy
  • 445
  • 6
  • 13
  • 2
    That's a massive [useless use of `echo` in backticks](http://www.iki.fi/era/unix/award.html#echo) you have there. If the value of `$directory` contains something which `echo -e` will interpret as an escape code, it will result in the wrong string; and anyway, the purpose of `<<<` is so you can say simply `<<<"$directory"`. – tripleee May 18 '17 at 13:53
  • I edited to remove the remaining `echo` in command substitutions as well. It's an anti-idiom which exacerbates any quoting issues, and you had several. – tripleee May 19 '17 at 03:45
1

I'm not too proficient in bash, so I won't give you a straight coded answer, but here's how you can achieve it.

From what I understand you are using 1 ls command to list the whole file system.

That will take a long time. Instead, use ls to list only folders in the current directory, pick a random one and then do the same to the one you picked.

This could go on until you get to a folder with no folders inside it.

If you want to have the possibility of picking a folder which does contain other folders and stop there, include in your random picking, an option that will not pick any file and stop in current directory. This option should have a small probability of occuring.

1

Here is a quick and dirty attempt.

randomcd () {
    local p=$(printf '%s\n' . */ | sort -R | head -n 1)
    case $p in '.' | '*/') pwd; return;; esac
    ( cd "$p"; randomcd )
}

Unfortunately sort -R is not entirely portable. If you don't have shuf either, something like this might work:

shuffle () {
    perl -MList::Util -e 'print List::Util::shuffle <>'
}
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 1
    You can remove `.` from the `printf` argument list if you want to always `cd` to a leaf directory, but then it's even less properly random. – tripleee May 18 '17 at 12:34