Formatting ls output without tab using awk? - linux

My question may seem fairly simple, I'm a beginner at bash scripting still, but I'm trying to format my ls output without using a tab when I print with awk.
Here is my current command that I'm running:
ls -al | sed 1d | awk '{print $1" ",$6" ", $7"\t", $9}'
and it prints out the following
drwx------ Feb 13 .
drwxr-xr-x Feb 5 ..
-rw-r--r-- Jan 21 .alias
-rw-r--r-- Feb 13 .bash_history
-rw-r--r-- Jan 29 .bash_profile
-rw-r--r-- Jan 21 .bash_profile~
-rw-r--r-- Feb 13 .bashrc
-rw-r--r-- Jan 21 .bashrc~
drwxr-xr-x Jan 3 csc135
drwxr-xr-x Aug 13 csc136
drwxr-xr-x Feb 9 csc235
drwxr-xr-x Oct 19 csc237
drwxr-xr-x Feb 18 csc310
drwxr-xr-x Feb 6 csc325
I have also attempted using a space:
ls -al | sed 1d | awk '{print $1" ",$6" ", $7" ", $9}'
which prints the following (quite bothersome):
drwx------ Feb 13 .
drwxr-xr-x Feb 5 ..
-rw-r--r-- Jan 21 .alias
-rw-r--r-- Feb 13 .bash_history
-rw-r--r-- Jan 29 .bash_profile
-rw-r--r-- Jan 21 .bash_profile~
-rw-r--r-- Feb 13 .bashrc
-rw-r--r-- Jan 21 .bashrc~
drwxr-xr-x Jan 3 csc135
drwxr-xr-x Aug 13 csc136
drwxr-xr-x Feb 9 csc235
drwxr-xr-x Oct 19 csc237
drwxr-xr-x Feb 18 csc310
drwxr-xr-x Feb 6 csc325
Is there any way to make it nicer looking like this?
drwx------ Feb 13 .
drwxr-xr-x Feb 5 ..
-rw-r--r-- Jan 21 .alias
-rw-r--r-- Feb 13 .bash_history
-rw-r--r-- Jan 29 .bash_profile
-rw-r--r-- Jan 21 .bash_profile~
-rw-r--r-- Feb 13 .bashrc
-rw-r--r-- Jan 21 .bashrc~
drwxr-xr-x Jan 3 csc135
drwxr-xr-x Aug 13 csc136
drwxr-xr-x Feb 9 csc235
drwxr-xr-x Oct 19 csc237
drwxr-xr-x Feb 18 csc310
drwxr-xr-x Feb 6 csc325

One automatic option that comes to mind is column:
$ ls -al | sed 1d | awk '{print $1,$6,$7,$9}' | column -t
drwxr-xr-x+ Feb 3 .
drwxrwxrwt+ Oct 9 ..
-rw------- Feb 12 .bash_history
-rwxr-xr-x Oct 9 .bash_profile
-rwxr-xr-x Feb 3 .bashrc
drwx------+ Feb 2 .cache
-rwxr-xr-x Oct 9 .inputrc
-rwxr-xr-x Feb 14 .mkshrc
-rwxr-xr-x Oct 9 .profile
drwxrwx---+ Dec 13 .ssh
Note the -t flag used for column:
-t, --table
Determine the number of columns the input contains and create
a table. Columns are delimited with whitespace, by default,
or with the characters supplied using the --output-separator
option. Table output is useful for pretty-printing.
Another way would be to used fixed lengths:
$ ls -al | sed 1d | awk '{printf "%-12s %-3s %-2s %s\n", $1,$6,$7,$9}'
drwxr-xr-x+ Feb 3 .
drwxrwxrwt+ Oct 9 ..
-rw------- Feb 12 .bash_history
-rwxr-xr-x Oct 9 .bash_profile
-rwxr-xr-x Feb 3 .bashrc
drwx------+ Feb 2 .cache
-rwxr-xr-x Oct 9 .inputrc
-rwxr-xr-x Feb 14 .mkshrc
-rwxr-xr-x Oct 9 .profile
drwxrwx---+ Dec 13 .ssh
There is another example of this in the GNU Awk User's guide.

ls -al|awk 'NR>1{print $1,$6,$7,$9}'|column -t
you don't need to use sed to delete the first line. Awk can do this if NR>1 print

You can avoid all unnecessary pipes by using features of awk.
ls -al | awk -v OFS="\t" 'NR>1 { print $1, $6, $7, $9 }'
Use NR>1 to get rid of the unnecessary sed to delete the first row.
Use OFS variable to set the output field separator to tab there by removing the need for column.

Related

Linux sort by month and year

I am trying to sort this data by the date such as the Oct 30 2020 column however I am not sure how
here is my current command
sudo find / -maxdepth 4 -size +1M -exec ls -lh {} \; | sort -k 6hr
Here is my output
-rw-r--r-- 1 root root 80M Oct 30 2020 /usr/lib/x86_64-linux-gnu/libLLVM-11.so.1
-rw-r--r-- 1 root root 38M Aug 27 13:02 /var/cache/apt/srcpkgcache.bin
-rw-r--r-- 1 root root 38M Sep 6 15:57 /var/cache/apt/pkgcache.bin
-rw-r--r-- 1 root root 27M Mar 17 2020 /usr/lib/x86_64-linux-gnu/libicudata.so.66.1
-rwxr-xr-x 1 root root 27M Feb 2 2021 /usr/lib/snapd/snapd
-rwxr-xr-x 1 root root 23M Feb 2 2021 /usr/bin/snap
-rwxr-xr-x 1 root root 16M Feb 2 2021 /usr/lib/snapd/snap-bootstrap
-rwxr-xr-x 1 root root 12M Feb 2 2021 /usr/lib/snapd/snap-repair
-r--r--r-- 1 root root 9.5M Feb 19 2021 /usr/lib/udev/hwdb.bin
-rw-r--r-- 1 root root 9.0M Dec 18 2020 /usr/lib/x86_64-linux-gnu/libvulkan_intel.so
-rwxr-xr-x 1 root root 8.8M Feb 2 2021 /usr/lib/snapd/snap-preseed
-rw-r--r-- 1 root root 8.7M May 29 00:49 /usr/lib/x86_64-linux-gnu/libtsan.so.0.0.0
-rwxr-xr-x 1 root root 8.7M Feb 2 2021 /usr/lib/snapd/snap-recovery-chooser
-rwxr-xr-x 1 root root 8.3M Feb 2 2021 /usr/lib/snapd/snapctl
-rw-r--r-- 1 root root 7.2M Dec 18 2020 /usr/lib/x86_64-linux-gnu/libvulkan_radeon.so
-rw-r--r-- 1 root root 6.3M Dec 16 2020 /usr/lib/x86_64-linux-gnu/libpthread.a
-rwxr-xr-x 1 root root 5.8M Feb 2 2021 /usr/lib/snapd/snap-update-ns
-rw-r--r-- 1 root root 5.6M Jan 16 2020 /usr/lib/file/magic.mgc
-rw-r--r-- 1 root root 5.5M Dec 16 2020 /usr/lib/x86_64-linux-gnu/libc.a
-rwxr-xr-x 1 root root 5.3M Jul 28 2020 /usr/bin/python3.8
-rw-r--r-- 1 root root 5.2M Jul 28 2020 /usr/lib/x86_64-linux-gnu/libpython3.8.so.1.0
-r-xr-xr-x 2 admin1 admin1 4.7M Aug 26 02:01 /mnt/c/Windows/explorer.exe
-rwxr-xr-x 1 root root 4.6M Feb 2 2021 /usr/lib/snapd/snap-failure
-rwxrwxrwx 1 admin1 admin1 4.3M Jun 28 16:08 /mnt/c/Python39/python39.dll
-rwxr-xr-x 1 root root 3.9M Feb 2 2021 /usr/lib/snapd/snap-exec
-rw-r--r-- 1 root root 3.4M Oct 19 2020 /usr/lib/x86_64-linux-gnu/libperl.so.5.30.0
-rwxr-xr-x 2 root root 3.4M Oct 19 2020 /usr/bin/perl
Thanks so much!!
Or a version that uses a different magic spell for ls:
sudo find / -maxdepth 4 -size +1M -exec ls -lh --time-style=long-iso {} \; | sort -k6
Because it thoroughly annoys me that ls doesn't show years by default when timestamps lie within the last 6 months and MMM DD YYYY makes no sense to me in the first place I've exported TIME_STYLE=long-iso in my ~/.bashrc ... so much more logical and easy to sort.
You can do this with what is called a decorate + sort + undecorate approach where you decorate each line by adding a new column at the end (a new column 10) in the form yyyymmdd and then sort by the new last column and then remove (undecorate) the output by removing the last column.
awk is the normal choice, and this works quite well as long as the filenames do NOT contain whitespace (which would skew the column (field) count for awk).
In your case you could do:
sudo find / -maxdepth 4 -size +1M -exec ls -lh {} \; |
awk 'BEGIN {
m["Jan"]=1; m["Feb"]=2; m["Mar"]=3; m["Apr"]=4; m["May"]=5; m["Jun"]=6;
m["Jul"]=7; m["Aug"]=8; m["Sep"]=9; m["Oct"]=10; m["Nov"]=11; m["Dec"]=12}
{
year = ($8 ~ /:/) ? 2021 : $8
mon = (length(m[$6]) < 2) ? "0"m[$6] : m[$6]
day = (length($7) < 2) ? "0"$7 : $7
$(NF+1) = year mon day
}1
' | sort -k 10 | awk '{$NF = ""}1'
Above, the first call to awk decorates each line with the new yyyymmdd column (new column (field) 10) and then the results are sorted by field 10 with sort. The second awk command undecorates each line.
Example Use/Output
Taking your shown output and placing it in the file file you could sort as:
awk 'BEGIN {
m["Jan"]=1; m["Feb"]=2; m["Mar"]=3; m["Apr"]=4; m["May"]=5; m["Jun"]=6;
m["Jul"]=7; m["Aug"]=8; m["Sep"]=9; m["Oct"]=10; m["Nov"]=11; m["Dec"]=12}
{
year = ($8 ~ /:/) ? 2021 : $8
mon = (length(m[$6]) < 2) ? "0"m[$6] : m[$6]
day = (length($7) < 2) ? "0"$7 : $7
$(NF+1) = year mon day
}1
' file | sort -k 10 | awk '{$NF = ""}1'
-rw-r--r-- 1 root root 5.6M Jan 16 2020 /usr/lib/file/magic.mgc
-rw-r--r-- 1 root root 27M Mar 17 2020 /usr/lib/x86_64-linux-gnu/libicudata.so.66.1
-rw-r--r-- 1 root root 5.2M Jul 28 2020 /usr/lib/x86_64-linux-gnu/libpython3.8.so.1.0
-rwxr-xr-x 1 root root 5.3M Jul 28 2020 /usr/bin/python3.8
-rw-r--r-- 1 root root 3.4M Oct 19 2020 /usr/lib/x86_64-linux-gnu/libperl.so.5.30.0
-rwxr-xr-x 2 root root 3.4M Oct 19 2020 /usr/bin/perl
-rw-r--r-- 1 root root 80M Oct 30 2020 /usr/lib/x86_64-linux-gnu/libLLVM-11.so.1
-rw-r--r-- 1 root root 5.5M Dec 16 2020 /usr/lib/x86_64-linux-gnu/libc.a
-rw-r--r-- 1 root root 6.3M Dec 16 2020 /usr/lib/x86_64-linux-gnu/libpthread.a
-rw-r--r-- 1 root root 7.2M Dec 18 2020 /usr/lib/x86_64-linux-gnu/libvulkan_radeon.so
-rw-r--r-- 1 root root 9.0M Dec 18 2020 /usr/lib/x86_64-linux-gnu/libvulkan_intel.so
-rwxr-xr-x 1 root root 12M Feb 2 2021 /usr/lib/snapd/snap-repair
-rwxr-xr-x 1 root root 16M Feb 2 2021 /usr/lib/snapd/snap-bootstrap
-rwxr-xr-x 1 root root 23M Feb 2 2021 /usr/bin/snap
-rwxr-xr-x 1 root root 27M Feb 2 2021 /usr/lib/snapd/snapd
-rwxr-xr-x 1 root root 3.9M Feb 2 2021 /usr/lib/snapd/snap-exec
-rwxr-xr-x 1 root root 4.6M Feb 2 2021 /usr/lib/snapd/snap-failure
-rwxr-xr-x 1 root root 5.8M Feb 2 2021 /usr/lib/snapd/snap-update-ns
-rwxr-xr-x 1 root root 8.3M Feb 2 2021 /usr/lib/snapd/snapctl
-rwxr-xr-x 1 root root 8.7M Feb 2 2021 /usr/lib/snapd/snap-recovery-chooser
-rwxr-xr-x 1 root root 8.8M Feb 2 2021 /usr/lib/snapd/snap-preseed
-r--r--r-- 1 root root 9.5M Feb 19 2021 /usr/lib/udev/hwdb.bin
-rw-r--r-- 1 root root 8.7M May 29 00:49 /usr/lib/x86_64-linux-gnu/libtsan.so.0.0.0
-rwxrwxrwx 1 admin1 admin1 4.3M Jun 28 16:08 /mnt/c/Python39/python39.dll
-r-xr-xr-x 2 admin1 admin1 4.7M Aug 26 02:01 /mnt/c/Windows/explorer.exe
-rw-r--r-- 1 root root 38M Aug 27 13:02 /var/cache/apt/srcpkgcache.bin
-rw-r--r-- 1 root root 38M Sep 6 15:57 /var/cache/apt/pkgcache.bin
Note, you use of -exec in the find command is horribly inefficient and you are better served using the -printf option with available format specifiers that can create the file output in any order you like and decorate the output for you with yyyymmdd. That would save calling ls -lh on each file to produce the file listing.
There are other ways to approach this, so do not think this is the only one-way to do this. Further note the limitation on whitespace in the filename corrupting the fields if this approach is used.
GNU date can parse the format printed by ls. The following converts the date into Unix epoch seconds and uses a Schwartzian transform to sort the lines. The transform needs four steps:
Calculate the sort key
Prefix the data with the sort key
Sort the prefixed data
Remove the prefix
while read line; do
date=$(sed 's/ / /g' <<< "$line" | cut -d ' ' -f 6-8)
epoch=$(date -d "$date" +%s)
printf '%s %s\n' "$epoch" "$line"
done | sort -n | sed 's/^[0-9]* //'
But: Why you shouldn't parse the output of ls(1)
Instead it would be better to tell find to print just the time and the file name. This can be sorted, the sort key can be removed, and finally the file names can be passed to ls. But you have to use the option -f to keep the sort order.
sudo find / -maxdepth 4 -size +1M -printf "%C# %p\n" |
sort -n |
sed 's/^[0-9.]* //' |
xargs ls -flh

How to delete all directories except last 2 directories and the symlink pointed to those directories

I have below directory structure.
~/test_dir🍺$ls -lrt
total 8
drwxr-xr-x 5 kk Users 160B Apr 17 23:53 app1/
drwxr-xr-x 5 kk Users 160B Apr 17 23:53 app2/
drwxr-xr-x 5 kk Users 160B Apr 17 23:53 app3/
drwxr-xr-x 5 kk Users 160B Apr 17 23:53 app4/
drwxr-xr-x 5 kk Users 160B Apr 17 23:53 app5/
~/test_dir🍺$cd app1
~/test_dir/app1🍺$ls -rlt
total 0
drwxr-xr-x 2 kk 10677 64B Apr 19 14:16 release1/
drwxr-xr-x 2 kk 10677 64B Apr 19 14:16 release2/
drwxr-xr-x 2 kk 10677 64B Apr 19 14:16 release3/
drwxr-xr-x 2 kk 10677 64B Apr 19 14:16 release4/
drwxr-xr-x 2 kk 10677 64B Apr 19 14:17 release5/
drwxr-xr-x 2 kk 10677 64B Apr 19 14:17 relase23/
drwxr-xr-x 2 kk 10677 64B Apr 19 14:17 release8.9/
lrwxr-xr-x 1 kk 10677 8B Apr 19 14:18 Current# -> release4
~/test_dir🍺ls -t1 | tail -n +3 | grep -v Current
relase23/
release5/
release4/
release3/
release2/
release1/
How to keep or preserve only the last two directories which are modified recently including the symlinks and their respective directories pointed to them?
I have tried the below
~/test_dir🍺ls -t1 | tail -n +3 | grep -v Current
relase23/
release5/
release4/
release3/
release2/
release1/
~/test_dir/app1🍺$ls -t1 | tail -n +3 | grep -v Current | xargs rm -r
~/test_dir/app1🍺$ls -rlt
total 0
drwxr-xr-x 2 kk 10677 64B Apr 19 14:17 release8.9/
lrwxr-xr-x 1 kk 10677 8B Apr 19 14:18 Current# -> release4
but that one is even deleting the directories pointing to symlink , keeping only the broken symlink.
#!/bin/bash
array=("app1" "app2" "app3" "app4" "app5")
for ((i=0;i<${#array[#]};i++))
do
app=${array[$i]}
echo "the app dir name is: $app"
cd ~/test_dir/$app
count=$(ls -t1 | tail -n +4 | grep -v Current | wc -l)
echo "number of directories deleted are:"
if [ $count == 0 ]
then
echo "Nothing to delete"
echo " "
else
ls -t1 | tail -n +4 | grep -v Current| xargs rm -r
fi
done
exit
Expected results are
~/test_dir/app1🍺$ls -t1 | tail -n +3 | grep -v Current | xargs rm -r
~/test_dir/app1🍺$ls -rlt
total 0
drwxr-xr-x 2 kk 10677 64B Apr 19 14:16 release4/
drwxr-xr-x 2 kk 10677 64B Apr 19 14:17 release8.9/
lrwxr-xr-x 1 kk 10677 8B Apr 19 14:18 Current# -> release4
The release4/ shouldn't get deleted which points to symlink and the symlink too. Any help Thanks.
Assumptions:
You want to retain only the two directories last modified.
You do not want to remove symlinks at all.
kept=0
stat -c "%Y %n %F" * | sort -rn |
while read timestamp dir type
do [[ directory == "$type" ]] || continue
ls -ld $dir/ # for logging only
if (( kept++ < 2 ))
then echo "Keeping $dir"
else echo "Removing $dir"
rm -fr $dir
fi
done
This will not address symlinks at all, though we could add that if you want it. The same is true for plain files, etc.
...Don't parse ls
SKIP="$(readlink Current#)";ls -trd release*|grep -v "^$SKIP$"|head -n -1|while read f;do rm -rf rela* "$f";done
EDIT 2:
The OP changed the specification slightly: There are also other directories.
18.09/ 19.01/ 19.02/ 19.03/ 19.05/ 19.04/
I slightly changed the "one liner" to capture also THIS:
[user123#matrix app1]$ mkdir 18.09/ 19.01/ 19.02/ 19.03/ 19.05/ 19.04/
[user123#matrix app1]$ ls -ltr
insgesamt 28
drwxrwxr-x. 2 user123 user123 4096 19. Apr 14:16 release4
lrwxrwxrwx. 1 user123 user123 8 19. Apr 14:18 Current# -> release4
-rw-rw-r--. 1 user123 user123 0 20. Apr 01:45 1
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.05
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.04
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.03
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.02
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.01
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 18.09
[user123#matrix app1]$ SKIP="$(readlink Current#)";ls -tr|egrep -v "^$SKIP$|^Current#$"|head -n -1|while read f;do rm -rf "$f";done
[user123#matrix app1]$ ls -l
insgesamt 8
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 18.09
lrwxrwxrwx. 1 user123 user123 8 19. Apr 14:18 Current# -> release4
drwxrwxr-x. 2 user123 user123 4096 19. Apr 14:16 release4
[user123#matrix app1]$

Difference b/w ls -la and ls -la > ls-1.txt

If I do ls -la, I get results like
total 16
drwxr-xr-x 4 rockse staff 136 Apr 28 16:55 .
drwx------+ 23 rockse staff 782 Apr 28 16:48 ..
-rw-r--r-- 1 rockse staff 32 Apr 28 16:49 1.sh
-rw-r--r-- 1 rockse staff 215 Apr 28 17:01 ls-1.txt
But if I do ls -la > ls-1.txt, I get this
total 8
drwxr-xr-x 4 rockse staff 136 Apr 28 16:55 .
drwx------+ 23 rockse staff 782 Apr 28 16:48 ..
-rw-r--r-- 1 rockse staff 32 Apr 28 16:49 1.sh
-rw-r--r-- 1 rockse staff 0 Apr 28 17:06 ls-1.txt
I understand that a file is created and then ls -la is written to the same but why doesn't it capture the snapshot of ls -la before creating the file because we are just writing stdout to a file ?
The redirection is done by the shell, not the program you're running. The processing done by the shell to implement this is similar to this (simplified):
Fork a child process
Open the output file
Connect stdout to the output file stream
Execute the program
Step 2 creates the file, so it will be visible when the program runs in step 4.
If step 2 were done after step 4, it wouldn't be possible to change the program's stdout to point to it.

find command with -atime appears to ignore dates

This command doesn't behave as I would expect. -atime +1 says "anything accessed within the last 24 hours", correct?
Output:
find . -type f -atime +1 -name 'installActions2*.log' | xargs ls -lt
-rw-r----- 1 bordb oinstall 369657 Nov 15 19:41 ./oms_b4_18604893.bak.15_Nov_14/cfgtoollogs/oui/installActions2014-03-17_09-18-01-PM.log
-rw-r----- 1 andy oinstall 1749422 Mar 17 2014 ./oracle_common/cfgtoollogs/oui/installActions2014-03-17_09-25-00-PM.log
-rw-r----- 1 andy oinstall 369657 Mar 17 2014 ./oms/cfgtoollogs/oui/installActions2014-03-17_09-18-01-PM.log
-rw-r----- 1 andy oinstall 600584 Mar 17 2014 ./jdk16/cfgtoollogs/oui/installActions2014-03-17_06-18-27PM.log
why are the files from March of 2014 and November showing up? So assuming the -atime switch says, "modified earier than the last 24 hours", I changed it to 60, and it lists the current directory, and all its files (ignores the -name switch) and doesn't traverse the subdirectories.
/ora/oracle/product/middleware_12cr3 Unix> find . -type f -atime +60 -name 'installActions2*.log' | xargs ls -lt
total 204
drwxr-xr-x 53 andy oinstall 4096 Jan 8 00:05 oms
drwxr-x--- 51 andy oinstall 4096 Jan 8 00:05 Oracle_WT
drwxr-x--- 33 andy oinstall 4096 Jan 7 22:09 oracle_common
drwxr-xr-x 2 andy oinstall 4096 Nov 20 07:45 logs
drwxr-xr-x 52 andy oinstall 4096 Nov 15 19:44 oms_b4_18604893.bak.15_Nov_14
drwxr-xr-x 10 andy oinstall 4096 Jun 18 2014 plugins
drwxr-xr-x 9 andy oinstall 4096 Jun 2 2014 wlserver_10.3
-rw-rw---- 1 andy oinstall 520 Mar 18 2014 domain-registry.xml
drwxr-x--- 3 andy oinstall 4096 Mar 18 2014 user_projects
drwxr-xr-x 5 andy oinstall 4096 Mar 17 2014 patch_wls1036
-rw-r--r-- 1 andy oinstall 1826 Mar 17 2014 registry.xml
-rw-r--r-- 1 andy oinstall 622 Mar 17 2014 ocm.rsp
-rw-r--r-- 1 andy oinstall 108917 Mar 17 2014 registry.dat
drwxr-xr-x 8 andy oinstall 4096 Mar 17 2014 utils
drwxr-xr-x 7 andy oinstall 36864 Mar 17 2014 modules
drwxr-xr-x 6 andy oinstall 4096 Mar 17 2014 jdk16
anyone know the reason? Sorry if this not an advanced question.
The -*time args to find consider time as growing larger in the past. So +1 means "more than one day ago", not "after one day ago". Try -1 to mean "less than one day ago".

Finding all directories that are world readable

**I cannot use find as I get a permission denied error
I am trying to find all the directories in /students that are world readable. This is what I have so far:
grep 'r-x' | cut -c8-10 | ls -l /students | sort | uniq -c
I don't understand why this is not working. I am telling the shell to search for occurrences of 'r-x'in the 8th-10th characters of ls -l which is other users permissions (hence world readable). Then I'm sorting the output and displaying a count of matching results with uniq -c. This is my understanding of what my shell script should do and I dont see why its not. Any help would be greatly appreciated!
For some reason it's pulling out more than just the directories readable by others.
Here is some sample output (I omitted the majority of the output)
1 drwx------ 11 lluong b20107 4096 May 26 11:15 lluong
1 drwx------ 23 stretbar b20097 4096 Dec 18 2012 stretbar
1 drwx------ 2 slawson b20003 4096 Mar 2 2013 slawson
1 drwx------ 9 fcunha b20117 4096 May 2 15:21 fcunha
1 drwxrwxrwx 10 jwu131 b20117 4096 Jul 2 19:26 jwu131
1 drwxrwxrwx 14 jadler4 b20127 4096 Oct 11 2012 jadler4
1 drwxrwxrwx 5 rlicudo1 b20067 4096 Apr 3 15:28 rlicudo1
1 drwxrwxrwx 8 lkrubner b20107 4096 Oct 25 2011 lkrubner
1 drwxrwxrwx 9 klau53 b20133 4096 Mar 12 2013 klau53
1 drwxrwx--x 14 vrobins9 b20123 4096 Mar 4 2013 vrobins9
1 drwxr-xr-x 10 aguo3 b20107 4096 Sep 24 00:13 aguo3
1 drwxr-xr-x 10 mdanial b20123 4096 Apr 10 20:46 mdanial
1 drwxr-xr-x 11 49 users 4096 Mar 28 2013 trac
1 drwxr-xr-x 11 rroger12 b20133 4096 May 8 10:00 rroger12
1 drwxr-xr-x 12 spark15 b20113 4096 May 15 2012 spark15
1 drwxr-xr-x 18 lulrich1 b20133 4096 Sep 29 22:36 lulrich1
1 drwxr-xr-x 18 yliu192 b20127 4096 Sep 26 12:19 yliu192
1 drwxr-xr-x 19 dstein b20117 4096 Feb 9 2013 dstein
1 drwxr-xr-x 20 jgarc166 b20127 4096 Sep 12 19:22 jgarc166
1 drwxr-xr-x 2 root root 16384 Nov 15 2007 lost+found
1 drwxr-xr-x 4 jsarno b20113 4096 Dec 7 2011 jsarno
1 drwxr-xr-x 6 btaylo19 b20123 4096 Mar 5 2012 btaylo19
1 drwxr-xr-x 6 dtu b20093 4096 Apr 18 19:18 dtu
1 drwxr-xr-x 6 ewu2 b20133 4096 May 4 14:30 ewu2
1 drwxr-xr-x 6 smeehan b20053 4096 Aug 29 00:19 smeehan
1 drwxr-xr-x 6 ybondar2 b20027 4096 May 23 2012 ybondar2
1 drwxr-xr-x 7 apekar b20103 4096 May 10 00:22 apekar
1 drwxr-xr-x 7 root root 4096 Mar 28 2013 tracprojects
1 drwxr-xr-x 8 jhsiao b20117 4096 Jul 26 17:33 jhsiao
1 drwxr-xr-x 8 xfeng18 b20137 4096 Sep 25 14:42 xfeng18
1 drwxr-xr-x 9 cmendo26 b20133 4096 Aug 19 01:22 cmendo26
1 drwx-----x 8 amissiro b20093 4096 May 12 16:00 amissiro
1 drwx--xr-x 17 apinchuk b20127 4096 May 26 23:03 apinchuk
1 drwx--x--x 10 aboak b20093 4096 Feb 18 2013 aboak
1 drwx--x--x 10 achan123 b20133 4096 Sep 6 21:24 achan123
1 drwx--x--x 10 acurkend b20133 4096 Jul 10 13:15 acurkend
1 drwx--x--x 10 akleinii b20133 4096 Jun 21 09:07 akleinii
1 drwx--x--x 10 akobzar b20133 4096 Sep 26 18:51 akobzar
1 drwx--x--x 10 amainett b20137 4096 Sep 22 11:17 amainett
1 drwx--x--x 10 apewther b20127 4096 Feb 6 2013 apewther
1 drwx--x--x 10 asyrtsov b20127 4096 Aug 16 10:43 asyrtsov
1 drwx--x--x 10 bernst b20135 4096 Sep 23 09:12 bernst
1 drwx--x--x 10 blilley b20123 4096 Apr 20 18:08 blilley
1 drwx--x--x 10 bmckeand b20117 4096 Aug 14 14:17 bmckeand
1 drwx--x--x 10 bsmith18 b20097 4096 Jun 10 11:19 bsmith18
1 drwx--x--x 10 bwilli18 b20117 4096 Nov 6 2012 bwilli18
1 drwx--x--x 10 cbeaton b20123 4096 May 19 04:07 cbeaton
1 drwx--x--x 10 cbeck4 b20137 4096 Sep 29 16:08 cbeck4
1 drwx--x--x 10 cho8 b20093 4096 Mar 24 2013 cho8
1 drwx--x--x 10 cliu58 b20117 4096 Oct 8 2012 cliu58
1 drwx--x--x 10 cmitch21 b20133 4096 Mar 10 2013 cmitch21
1 drwx--x--x 10 cnavarr9 b20127 4096 Apr 30 12:11 cnavarr9
1 drwx--x--x 10 dbienenf b20123 4096 Mar 20 2012 dbienenf
1 drwx--x--x 10 dlau13 b20135 4096 Jul 16 12:15 dlau13
1 drwx--x--x 10 dmok1 b20137 4096 Sep 24 12:50 dmok1
1 drwx--x--x 10 dnou b20133 4096 Apr 23 14:12 dnou
1 drwx--x--x 10 drajabar b20137 4096 Sep 3 20:20 drajabar
1 drwx--x--x 10 drodri12 b20115 4096 Sep 27 17:25 drodri12
1 drwx--x--x 10 ealberto b20113 4096 Dec 18 2012 ealberto
Rather than parsing ls, use find:
find /students -perm -o=r
This would list all files and directories in /students that are world readable.
If you don't want to recurse into subdirectories and want to find only directories, say:
find /students -maxdepth 1 -type d -perm -o=r
I am telling the shell to search for occurrences of 'r-x'in the 8th-10th characters of ls -l which is other users permissions (hence world readable).
No you're not. You're looking for "r-x" anywhere in the line and then taking the 8th through 10th characters of the lines found.
find /students -mindepth 1 -maxdepth 1 -type d -perm -005 | ...
"Why you shouldn't parse the output of ls(1)"
ls -lad */ | grep 'r-x' | sort | uniq -c
-d is used to list ONLY directories.
*/ tells *nix to search ONLY the current directory.
ls -lR |grep "^d" | cut -c8-10 | grep 'r-x' | sort | uniq -c

Resources