How do we display specific row of an output from bottom given line number?

I pass a number to my script. Passing "1" below.

./getfile.sh 1
echo "User entered: $1"
 ls -ltr *.conf | sed -n '$p'

I wish to use ls -ltr i.e list files in ascending order of time the latest showing at the bottom of the output.

Number 1 should get me the last row of ls -ltr output i.e the latest file.
Passing Number "2" should get me the second last row of the output.
Number "3 would get me the 3rd last row and so forth.

I wish to use only sed for this purpose as it is works smoothy across different flavors of Operating Systems that I have.

ls -ltr | sed -n '$p' gives me the last row whereas ls -ltr | sed -n 3p gives me the third row from top.

I'm not sure how can I give an equation so that based on user input, I could get my sed to display corresponding row of output.

You want the 3rd (...) newest file? Try NOT reversing the sorting order

ls -lt *.conf | sed -n "${1}p"
1 Like

If the user passes 1 then i need the newest latest file.

If the user passes 2 then i wish to display only the newest - 1 file i.e second latest file.

if the user passes 3 then the third latest file.

-bash-4.2$ ls -lt *.conf*
-rwxrwxrwx 1 user1 user 21627 Feb 11 17:17 httpd.conf_1581421731
-rwxrwxrwx 1 user1 user 15445 Feb 11 17:14 httpd-ssl.conf_1581421731
-rwxrwxrwx 1 user1 user 21624 Feb 11 17:13 httpd.conf_1581421456
-rwxrwxrwx 1 user1 user 15445 Feb 11 15:39 httpd-ssl.conf_1581421372
-rwxrwxrwx 1 user1 user 15445 Feb 11 15:39 httpd-ssl.conf_1581421456
-rwxrwxrwx 1 user1 user 21627 Feb 11 13:35 httpd.conf_1581408391
-rwxrwxrwx 1 user1 user 21627 Feb 11 13:35 httpd.conf_1581413246
-rwxrwxrwx 1 user1 user 21627 Feb 11 13:35 httpd.conf_1581415778
-rwxrwxrwx 1 user1 user 21627 Feb 11 13:35 httpd.conf_1581421372
-rwxrwxrwx 1 user1 user 21644 Feb 11 13:29 httpd.conf_1581408244
-rwxrwxrwx 1 user1 user 21644 Feb 11 13:29 httpd.conf_1581408293
-rwxrwxrwx 1 user1 user 21627 Feb 11 11:13 httpd.conf_1581399897
-rwxrwxrwx 1 user1 user 21627 Feb 11 11:13 httpd.conf_1581407966
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581399897
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581407966
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581408244
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581408293
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581408391
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581413246
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581415778
-bash-4.2$ ls -lt | sed -n "${1}p"
total 400
-rwxrwxrwx 1 user1 user 21627 Feb 11 17:17 httpd.conf_1581421731
-rwxrwxrwx 1 user1 user 15445 Feb 11 17:14 httpd-ssl.conf_1581421731
-rwxrwxrwx 1 user1 user 21624 Feb 11 17:13 httpd.conf_1581421456
-rwxrwxrwx 1 user1 user 15445 Feb 11 15:39 httpd-ssl.conf_1581421372
-rwxrwxrwx 1 user1 user 15445 Feb 11 15:39 httpd-ssl.conf_1581421456
-rwxrwxrwx 1 user1 user 21627 Feb 11 13:35 httpd.conf_1581408391
-rwxrwxrwx 1 user1 user 21627 Feb 11 13:35 httpd.conf_1581413246
-rwxrwxrwx 1 user1 user 21627 Feb 11 13:35 httpd.conf_1581415778
-rwxrwxrwx 1 user1 user 21627 Feb 11 13:35 httpd.conf_1581421372
-rwxrwxrwx 1 user1 user 21644 Feb 11 13:29 httpd.conf_1581408244
-rwxrwxrwx 1 user1 user 21644 Feb 11 13:29 httpd.conf_1581408293
-rwxrwxrwx 1 user1 user 21627 Feb 11 11:13 httpd.conf_1581399897
-rwxrwxrwx 1 user1 user 21627 Feb 11 11:13 httpd.conf_1581407966
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581399897
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581407966
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581408244
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581408293
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581408391
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581413246
-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581415778

Thus if the user passes 3 then the below file should be be printed

-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581408391

if the user passes 4 then the below file should be be printed

-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581408293

@Rudic your suggestion does not help get my desired output. Kindly suggest.

How can

-rwxrwxrwx 1 user1 user 15445 Feb 11 11:12 httpd-ssl.conf_1581408293

be the 4th newest file if

-rwxrwxrwx 1 user1 user 21627 Feb 11 17:17 httpd.conf_1581421731
-rwxrwxrwx 1 user1 user 15445 Feb 11 17:14 httpd-ssl.conf_1581421731
-rwxrwxrwx 1 user1 user 21624 Feb 11 17:13 httpd.conf_1581421456
-rwxrwxrwx 1 user1 user 15445 Feb 11 15:39 httpd-ssl.conf_1581421372

exist?

OK what have you done so far?

As we agree the first code you gave in #1 wont take you very far...

Passing numbers, OK but what if its not the case? like char or words, what happens?

Writing a script that accepts arguments is something nice, but unless its for your own usage, it should be fool proof and properly written Like :

No argument -> display usage

Testing the argument values etc...

@Rudic sorry that was by overlook. With parameter 3 the row returned should be the third row ie.

-rwxrwxrwx 1 user1 user 21624 Feb 11 17:13 httpd.conf_1581421456

Likewise when the user passes 4 the 4th latest row should be returned i.e

-rwxrwxrwx 1 user1 user 15445 Feb 11 15:39 httpd-ssl.conf_1581421372

But, as I shared the output of your suggestion i get a list of rows and not that single particular row corresponding to the argument passed to the script.

@vbe thank you for the points you highlighted however, the parameter is checked by a Jenkins UI tool and my script will only be executed once a number is passed to that script by the user. Thus the argument to my script is certainly an integer.

Kindly suggest

We have not seen any code so far and waiting to see this famous script...

Oh thats interesting, where is the code?

Did you have the first positional parameter set to 3 or 4? If empty, the entire list will be printed. As will easily be seen in an execution log...

q.e.d.

@Rudic thank you for the input and it is certainly returning a single row however not the intended row.

If you look at the output when i pass 4 to get the 4th row it returns the 3rd row as the first line / row of the output is total 400

-bash-4.2$ ls -lt | sed -n "${1}p"
total 400
-rwxrwxrwx 1 user1 user 21627 Feb 11 17:17 httpd.conf_1581421731
-rwxrwxrwx 1 user1 user 15445 Feb 11 17:14 httpd-ssl.conf_1581421731
-rwxrwxrwx 1 user1 user 21624 Feb 11 17:13 httpd.conf_1581421456
-rwxrwxrwx 1 user1 user 15445 Feb 11 15:39 httpd-ssl.conf_1581421372
./test.sh 4
-rwxrwxrwx 1 user1 user 21624 Feb 11 17:13 httpd.conf_1581421456

instead of the 4th row i.e.

-rwxrwxrwx 1 user1 user 15445 Feb 11 15:39 httpd-ssl.conf_1581421372

Now when i move from Linux to AiX (ksh shell) it does not print the first line and simply starts with the row printing the files. See output of AiX below:

/tmp>chmod 755 test.sh
/tmp>ls -lt *.log
-rw-rw-r--    1 root   dba        48969945 Feb 13 10:43 fatal.log
-rw-rw-r--    1 root   dba       102608600 Feb 13 10:43 fatal_info.log
-rw-rw-r--    1 root   dba       204800 Feb 13 10:16 vmt.log
-rw-rw-r--    1 root   dba     192437558 Feb 11 00:06 service.log

Thus, we are not sure if the first row total 400 will be printed everytime on each of the operating systems as it is a factor in deciding the row number. That is the very reason I was using ls -ltr instead of ls -lt and getting the latest timestamp file from bottom-top instead of top-bottom.

Can you please suggest ?

Which is correct since:

 ls -lt | sed -n "${1}p"

will return as first line:

total 400

So what you say the 3rd is not but the 4th
But

ls -lt *.log

returns without the total line as you specified what to return, and I doubt it being only specific to AIX, or linux on AIX

1 Like