@kyanny's blog

My thoughts, my life. Views/opinions are my own.

How to insert "repeating headers" into text file

Imagine you have a text file that contains output of ps -ef.
(you forgot to add --headers option)

UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 Apr02 ?        00:00:56 /sbin/init
root           2       0  0 Apr02 ?        00:00:00 [kthreadd]
root           3       2  0 Apr02 ?        00:00:00 [rcu_gp]
root           4       2  0 Apr02 ?        00:00:00 [rcu_par_gp]
root           6       2  0 Apr02 ?        00:00:00 [kworker/0:0H-kblockd]
root           9       2  0 Apr02 ?        00:00:00 [mm_percpu_wq]
root          10       2  0 Apr02 ?        00:00:11 [ksoftirqd/0]
root          11       2  0 Apr02 ?        00:00:16 [rcu_sched]
root          12       2  0 Apr02 ?        00:00:20 [migration/0]
root          13       2  0 Apr02 ?        00:00:00 [idle_inject/0]
root          14       2  0 Apr02 ?        00:00:00 [cpuhp/0]
root          15       2  0 Apr02 ?        00:00:00 [kdevtmpfs]
root          16       2  0 Apr02 ?        00:00:00 [netns]
root          17       2  0 Apr02 ?        00:00:00 [rcu_tasks_kthre]
root          18       2  0 Apr02 ?        00:00:00 [kauditd]
root          19       2  0 Apr02 ?        00:00:00 [khungtaskd]
root          20       2  0 Apr02 ?        00:00:00 [oom_reaper]
root          21       2  0 Apr02 ?        00:00:00 [writeback]
root          22       2  0 Apr02 ?        00:00:00 [kcompactd0]
root          23       2  0 Apr02 ?        00:00:00 [ksmd]
root          24       2  0 Apr02 ?        00:00:03 [khugepaged]
root          70       2  0 Apr02 ?        00:00:00 [kintegrityd]
root          71       2  0 Apr02 ?        00:00:00 [kblockd]
root          72       2  0 Apr02 ?        00:00:00 [blkcg_punt_bio]
root          73       2  0 Apr02 ?        00:00:00 [tpm_dev_wq]
root          74       2  0 Apr02 ?        00:00:00 [ata_sff]
root          75       2  0 Apr02 ?        00:00:00 [md]
root          76       2  0 Apr02 ?        00:00:00 [edac-poller]
root          77       2  0 Apr02 ?        00:00:00 [devfreq_wq]
root          78       2  0 Apr02 ?        00:00:00 [watchdogd]
root          81       2  0 Apr02 ?        00:00:00 [kswapd0]
root          82       2  0 Apr02 ?        00:00:00 [ecryptfs-kthrea]
root          84       2  0 Apr02 ?        00:00:00 [kthrotld]
root          85       2  0 Apr02 ?        00:00:00 [acpi_thermal_pm]
root          86       2  0 Apr02 ?        00:00:00 [vfio-irqfd-clea]
root          87       2  0 Apr02 ?        00:00:00 [ipv6_addrconf]
root          96       2  0 Apr02 ?        00:00:00 [kstrp]
root          99       2  0 Apr02 ?        00:00:00 [kworker/u3:0]
root         112       2  0 Apr02 ?        00:00:00 [charger_manager]
root         146       2  0 Apr02 ?        00:00:00 [cryptd]
root         158       2  0 Apr02 ?        00:00:16 [kworker/0:1H-kblockd]
root         166       2  0 Apr02 ?        00:00:00 [scsi_eh_0]
root         169       2  0 Apr02 ?        00:00:00 [scsi_tmf_0]
root         172       2  0 Apr02 ?        00:00:00 [scsi_eh_1]
root         174       2  0 Apr02 ?        00:00:00 [scsi_tmf_1]
root         175       2  0 Apr02 ?        00:00:00 [scsi_eh_2]
root         177       2  0 Apr02 ?        00:00:00 [scsi_tmf_2]
root         179       2  0 Apr02 ?        00:00:00 [scsi_eh_3]
root         181       2  0 Apr02 ?        00:00:00 [scsi_tmf_3]
root         182       2  0 Apr02 ?        00:00:00 [scsi_eh_4]
root         184       2  0 Apr02 ?        00:00:00 [scsi_tmf_4]
root         186       2  0 Apr02 ?        00:00:00 [scsi_eh_5]
root         188       2  0 Apr02 ?        00:00:00 [scsi_tmf_5]
root         234       2  0 Apr02 ?        00:00:00 [raid5wq]
root         272       2  0 Apr02 ?        00:00:09 [jbd2/vda1-8]
root         273       2  0 Apr02 ?        00:00:00 [ext4-rsv-conver]
root         308       2  0 Apr02 ?        00:00:00 [hwrng]
root         347       1  0 Apr02 ?        00:00:08 /lib/systemd/systemd-journald
root         372       1  0 Apr02 ?        00:00:18 /lib/systemd/systemd-udevd
root         449       2  0 Apr02 ?        00:00:00 [kaluad]
root         450       2  0 Apr02 ?        00:00:00 [kmpath_rdacd]
root         451       2  0 Apr02 ?        00:00:00 [kmpathd]
root         452       2  0 Apr02 ?        00:00:00 [kmpath_handlerd]
root         453       1  0 Apr02 ?        00:02:43 /sbin/multipathd -d -s
root         461       2  0 Apr02 ?        00:00:00 [loop0]
root         466       2  0 Apr02 ?        00:00:00 [loop2]
root         469       2  0 Apr02 ?        00:00:00 [loop4]
root         472       2  0 Apr02 ?        00:00:00 [loop5]
root         475       2  0 Apr02 ?        00:00:00 [loop6]
systemd+     499       1  0 Apr02 ?        00:00:08 /lib/systemd/systemd-timesyncd
systemd+     551       1  0 Apr02 ?        00:00:16 /lib/systemd/systemd-networkd
systemd+     553       1  0 Apr02 ?        00:00:06 /lib/systemd/systemd-resolved
root         589       1  0 Apr02 ?        00:00:39 /usr/lib/accountsservice/accounts-daemon
root         592       1  0 Apr02 ?        00:00:02 /usr/sbin/cron -f
message+     593       1  0 Apr02 ?        00:00:10 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root         600       1  0 Apr02 ?        00:00:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
syslog       601       1  0 Apr02 ?        00:00:00 /usr/sbin/rsyslogd -n -iNONE
root         609       1  0 Apr02 ?        00:00:08 /lib/systemd/systemd-logind
root         611       1  0 Apr02 ?        00:00:01 /usr/lib/udisks2/udisksd
daemon       614       1  0 Apr02 ?        00:00:00 /usr/sbin/atd -f
root         625       1  0 Apr02 ttyS0    00:00:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyS0 vt220
root         628       1  0 Apr02 tty1     00:00:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root         648       1  0 Apr02 ?        00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root         655       1  0 Apr02 ?        00:00:00 /usr/lib/policykit-1/polkitd --no-debug
root         670       1  0 Apr02 ?        00:00:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
root         695       1  0 Apr02 ?        00:00:00 /usr/sbin/squid -sYC
proxy        697     695  0 Apr02 ?        00:02:09 (squid-1) --kid squid-1 -sYC
proxy        699     697  0 Apr02 ?        00:00:00 (logfile-daemon) /var/log/squid/access.log
root         756     648  0 Apr02 ?        00:00:00 sshd: ubuntu [priv]
ubuntu       763       1  0 Apr02 ?        00:00:00 /lib/systemd/systemd --user
ubuntu       764     763  0 Apr02 ?        00:00:00 (sd-pam)
ubuntu       887     756  0 Apr02 ?        00:00:00 sshd: ubuntu@notty
ubuntu       906     763  0 Apr02 ?        00:00:00 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root         939     887  0 Apr02 ?        00:00:00 sudo env LD_LIBRARY_PATH=/snap/multipass-sshfs/145/lib /snap/multipass-sshfs/145/bin/sshfs -o slave -o transform_symlinks -o allow_other -o Compression=no -o dcache_timeout=3 :/Users/kyanny /home/ubuntu/Home/.
root         940     939  0 Apr02 ?        00:00:00 /snap/multipass-sshfs/145/bin/sshfs -o slave -o transform_symlinks -o allow_other -o Compression=no -o dcache_timeout=3 :/Users/kyanny /home/ubuntu/Home/.
root        7874       2  0 Apr03 ?        00:00:00 [loop7]
root        9187       2  0 Apr04 ?        00:00:00 [loop3]
root       16859       2  0 Apr04 ?        00:00:00 [xfsalloc]
root       16863       2  0 Apr04 ?        00:00:00 [xfs_mru_cache]
root       26521       2  0 Apr06 ?        00:00:00 [loop1]
root       26571       1  0 Apr06 ?        00:00:06 /usr/lib/snapd/snapd
root       26908       2  0 Apr06 ?        00:00:05 [kworker/0:2-events]
root       27009       2  0 Apr06 ?        00:00:00 [kworker/u2:1-events_power_efficient]
proxy      27030     697  0 00:00 ?        00:00:00 (pinger)
root       27034       2  0 00:00 ?        00:00:00 [kworker/u2:2-events_unbound]
root       27085       2  0 00:35 ?        00:00:00 [kworker/0:0-cgroup_destroy]
root       27195     648  0 00:35 ?        00:00:00 sshd: ubuntu [priv]
ubuntu     27268   27195  0 00:35 ?        00:00:00 sshd: ubuntu@pts/0
ubuntu     27269   27268  0 00:35 pts/0    00:00:00 -bash
root       27295       2  0 00:35 ?        00:00:00 [kworker/u2:0-events_unbound]
ubuntu     27359   27269  0 00:40 pts/0    00:00:00 ps -ef

This is not pager friendly because the header disappears in the subsequent pages.

To add the header repeatedly, I wrote a shell function(s).

  1. Using GNU sed (a little troublesome on macOS)

     heading(){
         local h="$(head -n 1 $1)"
         # terminal height - header - blank line - less footer
         local n=$(( $(tput lines) - 3 ))
         tail -n+2 $1 | gsed "1~${n} i\\\\" | gsed "/^$/ a $h" | gsed '1d'
     }
    
  2. Not using GNU sed (for platform portability)

     heading(){
         local h="$(head -n 1 $1)"
         # terminal height - header - blank line - less footer
         local n=$(( $(tput lines) - 3 ))
         tail -n+2 $1 | awk -v n=$n 'NR % n == 1 { print "" }; { print }' | sed "s/^$/\n$h/" | sed '1d'
     }
    

It recognizes your terminal height and insert headers into the appropriate places. Much friendly with pager like less.

Usage:

heading ps.txt

UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 Apr02 ?        00:00:56 /sbin/init
root           2       0  0 Apr02 ?        00:00:00 [kthreadd]
root           3       2  0 Apr02 ?        00:00:00 [rcu_gp]
root           4       2  0 Apr02 ?        00:00:00 [rcu_par_gp]
root           6       2  0 Apr02 ?        00:00:00 [kworker/0:0H-kblockd]
root           9       2  0 Apr02 ?        00:00:00 [mm_percpu_wq]
root          10       2  0 Apr02 ?        00:00:11 [ksoftirqd/0]
root          11       2  0 Apr02 ?        00:00:16 [rcu_sched]
root          12       2  0 Apr02 ?        00:00:20 [migration/0]
root          13       2  0 Apr02 ?        00:00:00 [idle_inject/0]
root          14       2  0 Apr02 ?        00:00:00 [cpuhp/0]
root          15       2  0 Apr02 ?        00:00:00 [kdevtmpfs]
root          16       2  0 Apr02 ?        00:00:00 [netns]
root          17       2  0 Apr02 ?        00:00:00 [rcu_tasks_kthre]
root          18       2  0 Apr02 ?        00:00:00 [kauditd]
root          19       2  0 Apr02 ?        00:00:00 [khungtaskd]
root          20       2  0 Apr02 ?        00:00:00 [oom_reaper]
root          21       2  0 Apr02 ?        00:00:00 [writeback]
root          22       2  0 Apr02 ?        00:00:00 [kcompactd0]
root          23       2  0 Apr02 ?        00:00:00 [ksmd]
root          24       2  0 Apr02 ?        00:00:03 [khugepaged]
root          70       2  0 Apr02 ?        00:00:00 [kintegrityd]
root          71       2  0 Apr02 ?        00:00:00 [kblockd]
root          72       2  0 Apr02 ?        00:00:00 [blkcg_punt_bio]
root          73       2  0 Apr02 ?        00:00:00 [tpm_dev_wq]
root          74       2  0 Apr02 ?        00:00:00 [ata_sff]
root          75       2  0 Apr02 ?        00:00:00 [md]
root          76       2  0 Apr02 ?        00:00:00 [edac-poller]
root          77       2  0 Apr02 ?        00:00:00 [devfreq_wq]
root          78       2  0 Apr02 ?        00:00:00 [watchdogd]
root          81       2  0 Apr02 ?        00:00:00 [kswapd0]
root          82       2  0 Apr02 ?        00:00:00 [ecryptfs-kthrea]
root          84       2  0 Apr02 ?        00:00:00 [kthrotld]
root          85       2  0 Apr02 ?        00:00:00 [acpi_thermal_pm]
root          86       2  0 Apr02 ?        00:00:00 [vfio-irqfd-clea]
root          87       2  0 Apr02 ?        00:00:00 [ipv6_addrconf]
root          96       2  0 Apr02 ?        00:00:00 [kstrp]
root          99       2  0 Apr02 ?        00:00:00 [kworker/u3:0]
root         112       2  0 Apr02 ?        00:00:00 [charger_manager]
root         146       2  0 Apr02 ?        00:00:00 [cryptd]
root         158       2  0 Apr02 ?        00:00:16 [kworker/0:1H-kblockd]
root         166       2  0 Apr02 ?        00:00:00 [scsi_eh_0]
root         169       2  0 Apr02 ?        00:00:00 [scsi_tmf_0]
root         172       2  0 Apr02 ?        00:00:00 [scsi_eh_1]
root         174       2  0 Apr02 ?        00:00:00 [scsi_tmf_1]
root         175       2  0 Apr02 ?        00:00:00 [scsi_eh_2]
root         177       2  0 Apr02 ?        00:00:00 [scsi_tmf_2]
root         179       2  0 Apr02 ?        00:00:00 [scsi_eh_3]

UID          PID    PPID  C STIME TTY          TIME CMD
root         181       2  0 Apr02 ?        00:00:00 [scsi_tmf_3]
root         182       2  0 Apr02 ?        00:00:00 [scsi_eh_4]
root         184       2  0 Apr02 ?        00:00:00 [scsi_tmf_4]
root         186       2  0 Apr02 ?        00:00:00 [scsi_eh_5]
root         188       2  0 Apr02 ?        00:00:00 [scsi_tmf_5]
root         234       2  0 Apr02 ?        00:00:00 [raid5wq]
root         272       2  0 Apr02 ?        00:00:09 [jbd2/vda1-8]
root         273       2  0 Apr02 ?        00:00:00 [ext4-rsv-conver]
root         308       2  0 Apr02 ?        00:00:00 [hwrng]
root         347       1  0 Apr02 ?        00:00:08 /lib/systemd/systemd-journald
root         372       1  0 Apr02 ?        00:00:18 /lib/systemd/systemd-udevd
root         449       2  0 Apr02 ?        00:00:00 [kaluad]
root         450       2  0 Apr02 ?        00:00:00 [kmpath_rdacd]
root         451       2  0 Apr02 ?        00:00:00 [kmpathd]
root         452       2  0 Apr02 ?        00:00:00 [kmpath_handlerd]
root         453       1  0 Apr02 ?        00:02:43 /sbin/multipathd -d -s
root         461       2  0 Apr02 ?        00:00:00 [loop0]
root         466       2  0 Apr02 ?        00:00:00 [loop2]
root         469       2  0 Apr02 ?        00:00:00 [loop4]
root         472       2  0 Apr02 ?        00:00:00 [loop5]
root         475       2  0 Apr02 ?        00:00:00 [loop6]
systemd+     499       1  0 Apr02 ?        00:00:08 /lib/systemd/systemd-timesyncd
systemd+     551       1  0 Apr02 ?        00:00:16 /lib/systemd/systemd-networkd
systemd+     553       1  0 Apr02 ?        00:00:06 /lib/systemd/systemd-resolved
root         589       1  0 Apr02 ?        00:00:39 /usr/lib/accountsservice/accounts-daemon
root         592       1  0 Apr02 ?        00:00:02 /usr/sbin/cron -f
message+     593       1  0 Apr02 ?        00:00:10 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root         600       1  0 Apr02 ?        00:00:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
syslog       601       1  0 Apr02 ?        00:00:00 /usr/sbin/rsyslogd -n -iNONE
root         609       1  0 Apr02 ?        00:00:08 /lib/systemd/systemd-logind
root         611       1  0 Apr02 ?        00:00:01 /usr/lib/udisks2/udisksd
daemon       614       1  0 Apr02 ?        00:00:00 /usr/sbin/atd -f
root         625       1  0 Apr02 ttyS0    00:00:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyS0 vt220
root         628       1  0 Apr02 tty1     00:00:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root         648       1  0 Apr02 ?        00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root         655       1  0 Apr02 ?        00:00:00 /usr/lib/policykit-1/polkitd --no-debug
root         670       1  0 Apr02 ?        00:00:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
root         695       1  0 Apr02 ?        00:00:00 /usr/sbin/squid -sYC
proxy        697     695  0 Apr02 ?        00:02:09 (squid-1) --kid squid-1 -sYC
proxy        699     697  0 Apr02 ?        00:00:00 (logfile-daemon) /var/log/squid/access.log
root         756     648  0 Apr02 ?        00:00:00 sshd: ubuntu [priv]
ubuntu       763       1  0 Apr02 ?        00:00:00 /lib/systemd/systemd --user
ubuntu       764     763  0 Apr02 ?        00:00:00 (sd-pam)
ubuntu       887     756  0 Apr02 ?        00:00:00 sshd: ubuntu@notty
ubuntu       906     763  0 Apr02 ?        00:00:00 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root         939     887  0 Apr02 ?        00:00:00 sudo env LD_LIBRARY_PATH=/snap/multipass-sshfs/145/lib /snap/multipass-sshfs/145/bin/sshfs -o slave -o transform_symlinks -o allow_other -o Compression=no -o dcache_timeout=3 :/Users/kyanny /home/ubuntu/Home/.
root         940     939  0 Apr02 ?        00:00:00 /snap/multipass-sshfs/145/bin/sshfs -o slave -o transform_symlinks -o allow_other -o Compression=no -o dcache_timeout=3 :/Users/kyanny /home/ubuntu/Home/.
root        7874       2  0 Apr03 ?        00:00:00 [loop7]

UID          PID    PPID  C STIME TTY          TIME CMD
root        9187       2  0 Apr04 ?        00:00:00 [loop3]
root       16859       2  0 Apr04 ?        00:00:00 [xfsalloc]
root       16863       2  0 Apr04 ?        00:00:00 [xfs_mru_cache]
root       26521       2  0 Apr06 ?        00:00:00 [loop1]
root       26571       1  0 Apr06 ?        00:00:06 /usr/lib/snapd/snapd
root       26908       2  0 Apr06 ?        00:00:05 [kworker/0:2-events]
root       27009       2  0 Apr06 ?        00:00:00 [kworker/u2:1-events_power_efficient]
proxy      27030     697  0 00:00 ?        00:00:00 (pinger)
root       27034       2  0 00:00 ?        00:00:00 [kworker/u2:2-events_unbound]
root       27085       2  0 00:35 ?        00:00:00 [kworker/0:0-cgroup_destroy]
root       27195     648  0 00:35 ?        00:00:00 sshd: ubuntu [priv]
ubuntu     27268   27195  0 00:35 ?        00:00:00 sshd: ubuntu@pts/0
ubuntu     27269   27268  0 00:35 pts/0    00:00:00 -bash
root       27295       2  0 00:35 ?        00:00:00 [kworker/u2:0-events_unbound]
ubuntu     27359   27269  0 00:40 pts/0    00:00:00 ps -ef


Alternatively, using VisiData is the easiest way.

vd -f tsv ps.txt