-1

I studied that

ls -dtr1 * | tail -5 | awk 'NR==2'

lists the second last folder created among the last 5 folders created.

I wanted to use it inside a for loop: So i created a shell script forLoopExample.sh

for ii in $(seq 1 $1)
do
  f_name=`ls -dtr1 * | tail -$1 | awk 'NR==$ii'`
 # mkdir $f_name in some other location
 # and some other operations 

done

I expected if i do sh forLoopExample.sh 3 the loop runs three times and does the expected operation for all the three folders. but mkdir is throwing error. enter image description here

Kindly help me in solving the error. Thanks in advance.

srk_cb
  • 129
  • What does the picture show? – Chris Davies Dec 29 '20 at 09:52
  • 4
    The shell doesn't substitute variables in single-quotes, so the $ii in the awk command isn't doing what you want. You could use double-quotes instead, but it's really better to use awk's -v option to copy the shell variable into an awk variable (see this Q/A). BTW, I also recommend using shellcheck.net to check your script for other common mistakes. – Gordon Davisson Dec 29 '20 at 10:07

1 Answers1

0

There are at least three issues with your code:

  1. You try to use a shell variable inside an awk program. The correct way to do that is to make an awk variable with the value of the shell variable:

     awk -v line="$ii" 'NR == line'
    
  2. You use C-like /* ... */ comments in a shell script. Comments in shell scripts are introduced with # and stretches to the next newline character.

  3. You rely on parsing ls to get names in timestamp order. This would break if a name contained a newline character. Instead, use something like

     f_name=$( zsh -c 'print -rC1 *(/om[$1])' zsh "$ii" )
    

This uses the zsh shell to get the ii:th most recently modified directory name in the current directory. Note that the mtime timestamp on a directory is updated when a directory entry is added or deleted in the directory, not if an existing file is updated or if things are added to or removed from subdirectories.

In zsh, looping over the directories in the current directory in order of mtime timestamp:

for dir in *(/om); do
    # use "$dir" here
done

Use *(/om[1,$1]) as the pattern to only loop over the first $1 most recently modified directories.

See also:

Kusalananda
  • 333,661