Praveen Mishra
Praveen Mishra

Reputation: 151

Use unix command inside awk commandline to process fields

Is there a way to use unix command inside awk one-liner to do something and output the result on STDIN?

For example:

ls -lrt|awk '$8 !~ /:/ {system(date -d \"$6" "$7" "$8\" +"%Y%m%d")"|\t"$0}'

Upvotes: 0

Views: 118

Answers (3)

Dudi Boy
Dudi Boy

Reputation: 4865

You are trying to format the date output from ls.

The find command has extensive control over date and time output. Using -printf action.

For examples here:

$ ls -l
-rw-rw-r--. 1 cfrm cfrm 41 Nov 15 09:12 input.txt
-rw-rw-r--. 1 cfrm cfrm 67 Nov 15 09:13 script.awk

$ find . -printf "fileName=%f \t formatedDate-UTC=[%a] \t formatedDate-custom=[%AY-%Am-%Ad]\n"
fileName=.       formatedDate-UTC=[Fri Nov 15 09:43:32.0222415982 2019]          formatedDate-custom=[2019-11-15]
fileName=input.txt       formatedDate-UTC=[Fri Nov 15 09:12:33.0117279463 2019]          formatedDate-custom=[2019-11-15]
fileName=script.awk      formatedDate-UTC=[Fri Nov 15 09:13:38.0743189896 2019]          formatedDate-custom=[2019-11-15]

For sorting by timestamp, we can mark the sorting to start on the timestamp marker ([ in the following example)

$ find . -printf "%f timestamp=[%AY%Am%Ad:%AT]\n" |sort -t [
22114 timestamp=[20190511:10:32:22.6453184660]
5530 timestamp=[20190506:01:03:01.2225343480]
5764 timestamp=[20190506:01:03:34.7107944450]
.font-unix timestamp=[20191115:13:27:01.8699219890]
hsperfdata_artemis timestamp=[20191115:13:27:01.8699219890]
hsperfdata_cfrm timestamp=[20191115:13:27:01.8709219730]
hsperfdata_elasticsearch timestamp=[20191115:13:27:01.8699219890]
.ICE-unix timestamp=[20191115:13:27:01.8699219890]
input.txt timestamp=[20191115:09:12:33.1172794630]
junk timestamp=[20191115:09:43:32.2224159820]
script.awk timestamp=[20191115:09:13:38.7431898960]
systemd-private-1a6c51334d6f4723b46fe5ca51b632c6-chronyd.service-AoZvZM timestamp=[20190516:05:09:51.1884573210]
systemd-private-1a6c51334d6f4723b46fe5ca51b632c6-vgauthd.service-f2m9rt timestamp=[20190516:05:09:51.1884573210]
systemd-private-1a6c51334d6f4723b46fe5ca51b632c6-vmtoolsd.service-0CJ32C timestamp=[20190516:05:09:51.1884573210]
.Test-unix timestamp=[20191115:13:27:01.8699219890]
. timestamp=[20191115:13:26:56.8770048750]
.X11-unix timestamp=[20191115:13:27:01.8699219890]
.XIM-unix timestamp=[20191115:13:27:01.8699219890]

Upvotes: 0

Walter A
Walter A

Reputation: 20002

You are parsing ls, which can cause several problems. When you are trying to get your filenames order by last modification with yyyymmdd in front of it, you can look at

# not correct for some filenames
stat --format "%.10y %n" * | tr -d '-' | sort

The solution fails for filenames with -. One way to solve that is using

# Still not ok
stat --format "%.10y %n" * | sed -r 's/^(..)-(..)/\1\2/' | sort

This will fail for filenames with newlines.

touch -d "2019-09-01 12:00:00" "two
lines.txt"

shows some of the problems you can also see with ls.
How you should solve this depends on your exact requirements.
Example

find . -maxdepth 1  ! -name "[.]*" -printf '%TY%Tm%Td ' -print0 |
   sed 's#[.]/##g'|  tr "\n\0" "/\n" | sort

Explanation:
maxdepth 1 Only look in current directory
! -name "[.]*" Ignore hidden files
-printf '%TY%Tm%Td ' YYYYMMDD and space
-print0 Don't use \n but NULL at the end of each result
sed 's#[.]/##g' Remove the path ./
tr "\n\0" "/\n" Replace newlines in a filename with / and NULLs with newlines

After the sort you might want to tr '|' '\n'.

Upvotes: 1

Kent
Kent

Reputation: 195049

If you want to have the output of the command, you can make use of getline:

kent$  awk 'BEGIN{"date"|getline;print}'
Fri 15 Nov 2019 10:51:10 AM CET

You can also assign the output to an awk variable:

kent$  awk 'BEGIN{"date"|getline v;print v}'        
Fri 15 Nov 2019 10:50:20 AM CET

Upvotes: 0

Related Questions