Reputation: 35
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!!
Upvotes: 0
Views: 717
Reputation: 23824
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:
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
Upvotes: 0
Reputation: 15214
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.
Upvotes: 1
Reputation: 84561
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.
Upvotes: 1