bash: Pass through header untouched in pipeline

TLDR; Use (read; println; foo)

If some input has one or more lines of input that should not be processed, i.e. header rows, it can be useful to output them untouched then process the rest of the input through some pipeline.

By using a bash subshell we can explicitly read and println a line of input, then handle the rest of the input with subsequent commands.

foo | ( read; printf "%s\n" "$REPLY"; bar ) | baz

Example

$ ls -al | head -4
total 904
drwxr-xr-x@ 28 nick  staff     896 12 Sep 13:31 .
drwxr-xr-x@  5 nick  staff     160  5 Sep 02:25 ..
drwxr-xr-x@ 12 nick  staff     384 12 Sep 13:31 .git

If we wanted to retain "total ..." but sort the other rows by the 5th field we could do the following:

$ ls -al | head -4 | ( read; printf "%s\n" "$REPLY"; sort -nk5,5 )
20220912132237.mds
drwxr-xr-x@  5 nick  staff     160  5 Sep 02:25 ..
drwxr-xr-x@ 12 nick  staff     384 12 Sep 13:31 .git
drwxr-xr-x@ 28 nick  staff     896 12 Sep 13:31 .
Published on: 12 Sep 2022