Insert FF (feed form) in text file so that when printing the printer print on a new page accordingly

Hello.
First happy new year to everybody.

I have a script that generate a text file ( /tmp/part_list.txt for example ).
This file can be edited using a kde graphical text editor like kate or kwrite
The file can be printed out from command line or within the text editor using the print option menu.


echo "" > /tmp/part_list.txt
echo "" > /tmp/part_list.txt
 
for A_DEVICE in $(lsblk --noheadings -o kname) ; do...
...
        CUR_DEVICE="$A_DEVICE"      # A_DEVICE = /dev/sda /dev/sdb /dev/sdc .....  
        gdisk -l "$CUR_DEVICE"  >>  /tmp/part_list.txt  2>&1

done

Now I would like to add the code so that when printing the file "/tmp/part_list.txt" the printer change page after each device
Something like that :


echo "" > /tmp/part_list.txtecho "" > /tmp/part_list.txt

for A_DEVICE in $(lsblk --noheadings -o kname) ; do...
...
        CUR_DEVICE="$A_DEVICE"      # A_DEVICE = /dev/sda /dev/sdb /dev/sdc .....  
        gdisk -l "$CUR_DEVICE"  >>  /tmp/part_list.txt  2>&1
        echo "some code that printer understand as do FF" >> /tmp/part_list.txt  
done


And then the file "/tmp/part_list.txt" contains some thing like :

device : /dev/sda

ligne of text
ligne of text
ligne of text
ligne of text
ligne of text
ligne of text
ligne of text
0x0c  or  do FF or .....?
device : /dev/sdb

ligne of text
ligne of text
ligne of text
ligne of text
ligne of text
ligne of text
ligne of text0x0c  or  do FF or .....?
device : /dev/sdc

ligne of text
ligne of text
ligne of text
ligne of text
ligne of text
ligne of text
ligne of text



Any help is welcome.

Notice that such a function is usually located in the printers (or, more precisely, the printer queues) backend and you are - by trying to do what you do - second-guessing the work of it. Chances are this might get filtered out in the processing the printer driver does after you send it to the queue.

Some historical background on where that mattered: you probably know that the line-feed sequence in UNIX is a "linefeed" character, whereas in DOS/Windoze it is a carriage-return plus a linefeed. The reason is: (dot-matrix) printers worked this way, the carriage-return moved the printing head back to the left side and the linefeed move the paper upwards. It was quite like the mechanical and electrical typewriters that preceeded printers. By having this sequence as a end-of-line sequence the makers of DOS could forego the necessity to write a printer driver for their OS. UNIX, on the other hand, had printer drivers and therefore didn't need a two-character sequence. Therefore it had (and has, up to this day) a one-character EOL sequence which is in turn changed to a CR+LF if you print something to one of these old dot-matrix printers with endless paper.

Now, consider what that would do to your print job if you would mess around with the EOL sequence yourself: most probably not what you wanted to have because between your artificially inserted characters and them being processed (and turned into something maybe completely different) by the driver the printer might get confused over the result.

My suggestion is: use a "high-level" document language (i.e. Postscript, TeX, PDF, ....) to create your report. You can easily force form-feeds (or, repectively, their equivalent) within these languages because the all have that. Then use a driver for the respective language (in fact there are even natively-capable Postscript printers) to process your generated file into a correct print job. This way you are save from unknown (and unwanted) side effects and furthermore you are not bound to a specific printer model. All the mentioned languages are quasi-standards and you can easily swap one i.e. Postscript-capable printer for another Postscript-capable printer and the printed result will guaranteed to look the same.

I hope this helps.

bakunin

1 Like

replace the line 'echo some code...'
with

echo -e "\f"
1 Like

If somebody has a better, shorter, cleaner solution tell me.

First create a groff file

echo "" > /tmp/part_list.groff echo ".nf" >> /tmp/part_list.groff  # NO FILL MODE 
FIRST_PASS="true"

for A_DEVICE in $(lsblk --noheadings -o kname) ; do
... 
...
...
    if [[ -z $FIRST_PASS ]] ; then
           echo ".bp" >> /tmp/part_list.groff  # do a page break if not processing the first device
        else
            FIRST_PASS=""
        fi
         CUR_DEVICE="$A_DEVICE"      # A_DEVICE = /dev/sda /dev/sdb /dev/sdc .....           
         gdisk -l "$CUR_DEVICE"  >>  /tmp/part_list.groff  2>&1  

done
 #
# Finished
#
echo ".pl -3" >> /tmp/part_list.groff  # i do adjustment because groff page length does not match 
                                                 # the page length of my laser printer
                                                 # so I got to much line feed.
echo ".ex" >> /tmp/part_list.groff     # No more to do

2) Build the text file :

groff -Tascii /tmp/part_list.groff > /tmp/part_list.txt

Any comment is welcome

I'm not at all sure that I follow what you're trying to do, but if you just want to insert a formfeed character before each occurrent of a line starting with the string "device" except the first one, I would be tempted to try a simple awk script:

awk '/^device/{if(seen++) printf "\f"}1' file

or, more simply, replace your first script:

echo "" > /tmp/part_list.txt
echo "" > /tmp/part_list.txt
 
for A_DEVICE in $(lsblk --noheadings -o kname) ; do...
...
        CUR_DEVICE="$A_DEVICE"      # A_DEVICE = /dev/sda /dev/sdb /dev/sdc .....  
        gdisk -l "$CUR_DEVICE"  >>  /tmp/part_list.txt  2>&1

done

with:

device_cnt=0
 
for A_DEVICE in $(lsblk --noheadings -o kname)
do	...
	device_cnt=$((device_cnt + 1))
	if [ $device_cnt -gt 1 ]
	then	printf '\f\n'
	else	echo
	fi
	gdisk -l "$A_DEVICE" 2>&1
done > /tmp/part_list.txt

(assuming, of course, that whatever code you showed as as ... doesn't write anything to standard output).

1 Like

Thank you very much