1

When I am doing

ls -la |grep -e Aug

I am getting the output as

-rw-r--r--    1 root           staff   454 Oct 15 18:35 Aug.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 25 04:00 abc7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 26 07:00 def7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 27 10:00 ghi7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 28 13:00 jkl7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 29 16:00 mno7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 30 19:00 pqr7.txt

I only want to list the files which are created on Aug not the first file which is created on Oct but has name Aug in it. Below should be the output

-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 25 04:00 abc7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 26 07:00 def7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 27 10:00 ghi7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 28 13:00 jkl7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 29 16:00 mno7.txt
-rwxr-xr-x@   1 PrashastKumar  staff     0 Aug 30 19:00 pqr7.txt

Also i want to take the month as user input not the hardcoded value.

2 Answers2

2

You should consider alternatives to parsing ls, which is rife with multiple pitfalls. But since your main interest here seems to be how to filter by column, and your ultimate goal may not be to parse ls anyway, I'll go ahead and stick with the example you're using (which uses ls). Please don't take this to mean parsing ls's output is a good thing to do, though. It's not usually a good thing to do.

When you grep for Aug, you're searching for it anywhere in a line. Really you don't want to select lines that contain Aug anywhere, but instead just those that have it as the complete and exact text of their sixth column. Although you can do this with grep, it is much easier and more natural with awk:

ls -la | awk '$6 == "Aug"'

If for some reason you really want to do this with grep, you can:

ls -la | grep -E '(\S+\s+){5}Aug\s'

You are also interested in filtering for lines whose sixth column is equal to a value that has been read into a shell variable month. You have observed that this does not work:

ls -la | awk '$6 == "$month"'   # does not work

The reason that does not work is that the single quotes around the AWK script $6 == "$month" prevent the shell from performing parameter expansion on $month to replace it with its value. The text $month is passed as-is to awk, which is not what you want. AWK variables and shell variables are completely separate. One clean and easy way to solve this problem is to initialize an AWK variable from the shell variable using the awk command's -v option:

ls -la | awk -v m="$month" '$6 == m'

You could name your AWK variable the same as your shell variable, if you like. This is a reasonable choice in cases like this where they represent the same thing. I've named the AWK variable m, to illustrate how shell and AWK variables are separate and also to avoid confusion. (For long or complicated AWK scripts, or those with many variables, you would probably want to name the variable more descriptively than just m, but in this case no readability is sacrificed.)


I've linked above to topics in the Bash reference manual because you've tagged your question and the default shell in all but the very oldest versions of OS X (now called macOS) is bash. In very old versions it was tcsh.

As a side note, you mentioned that you took the value of month as input with the command read month. When you use your shell's read command, you should almost always pass the -r flag, and thus write read -r month instead. Only omit -r if you want the read command to translate \ escapes in the input it receives (which you virtually never want). You may also want to use IFS= read -r month, so leading and trailing whitespace are not stripped. In this case, though, you likely do want it removed and can thus omit IFS=.

Eliah Kagan
  • 4,155
  • But when i am reading month from user as read month & passing the command as ls -la |awk ' $6 == "$month" ', its not working what is the reason for that – Prashast Oct 16 '17 at 02:16
  • @Prashast That's because month is a shell variable but the single quotes prevent the shell from expanding it before running awk. It seems to me that using a month name stored in a shell variable is an important part of what you're trying to do, so I've expanded my answer with an additional section about how to solve this problem. I would encourage you to edit your question and add that as well, though, so other readers know it's part of what you want to know. Other users may post helpful answers (like about doing it without ls) that will be more helpful if they know you want this. – Eliah Kagan Oct 16 '17 at 02:34
0

This one worked for me

ls -al | awk '$6 == "Aug" {print}'