4

How do I remove the ^L character and the blank lines that come after it on a unix file? I have tried the below and have been able to remove the VT and spaces but am failing to remove the ^L character and the blank lines after it

tr -s '\040\011\' '|' <$x>> modified.txt

and:

tr -d '\013'  <modified1.txt>> $FILENAME
1
  • 1
    FF is \014. \013 is VT (vertical tab). L is the 12th letter of the English alphabet (14 in octal). – Stéphane Chazelas Jul 31 '15 at 9:23
8

That's the caret notation for the form feed character. With the GNU implementation of sed, you can remove it using its octal value, \o14 :

sed 's/\o14//g' file 

You can also use its escape code:

sed 's/\f//' file

Such characters can be entered in the terminal by pressing CtrlV and then the code for the character. In this case, CtrlL. So, type this:

sed 's/

Then, hit CtrlV and then CtrlL:

sed 's/^L

Now, complete the command:

sed 's/^L//g' file

Don't write ^L and don't paste it from the above, use the keyboard shortcut I gave.

You could also remove it with tr:

tr -d '\f' < file

Or perl:

perl -pe 's/\f//g' file

To delete both the \f and any blank lines following it, you could do something like:

perl -0pe 's/\f\s*/\n/s' file
4

With ksh93, bash, zsh, mksh, recent FreeBSD sh:

sed $'/\f/,/./{/\f/d;/./!d;}'

That will fail if there are consecutive sequences of \f\n\n...s though.

With GNU sed, you can omit the $.

POSIXly ($'...' is not POSIX yet, though will probably be in SUSv5):

FF=$(printf '\f')
sed "/$FF/,/./{/$FF/d;/./!d;}"

Note that the current POSIX spec requires a newline instead of ; before }, but that's actually a bug in the POSIX spec as not even the initial implementation of sed ever required it.

7
  • 1
    Why the $' '? Isn't it sed that deals with interpreting the escape characters? Why use the ANSI escape for them? – terdon Jul 31 '15 at 9:15
  • any reason you don't stick a newline in before }? – mikeserv Jul 31 '15 at 9:31
  • 1
    @terdon, the only escape sequence POSIXly-supported on the LHS is \n, none on the RHS. GNU sed supports more, though when inside [...] that depends on whether POSIXLY_CORRECT is in the environment or not. – Stéphane Chazelas Jul 31 '15 at 10:15
  • 1
    @mikeserv, see austingroupbugs.net/view.php?id=944 The requirement for newline there was a bug in the spec, no implementation requires it (note that the report there is wrong in that you can't have ; after }, but it's fine before }). Will be fixed in the next version. – Stéphane Chazelas Jul 31 '15 at 10:22
  • So did you ever find out what Accepted as Marked means? That sed -E thing has been Accepted as Marked since 2012 I think - I think I recall some bugs kicking about Accepted as Marked about [[ ]] since 2011 or so (could be wrong about that bit, though). I'm also looking forward to tail -r - but I can't figure out what Accepted as Marked is supposed to mean. – mikeserv Jul 31 '15 at 15:33
1
sed "$(printf '$!N;/\f')"'\n/,/\n./!P;D' <in >out

...should work provided a POSIX compliant shell, printf, and sed.

You don't really need printf though if you just insert the character literally. You can usually do it with CTRL+V then CTRL+L.

So...

sed '$!N;/^L\n/,/\n./!P;D' <in >out

...where the ^L sequence above is got by doing CTRL+V then CTRL+L and represents the literal form feed character.

5
  • Does POSIX sed not support \f? – terdon Jul 31 '15 at 10:10
  • @terdon - sure, as a printf argument. But to a POSIX sed \f is just f. – mikeserv Jul 31 '15 at 10:14
  • Yeah, I was asking for sed itself, but it seems that it only understands \n. – terdon Jul 31 '15 at 10:48
  • @terdon, to a POSIX sed, \f is unspecified, so any behaviour (including rebooting the computer or matching the FF or 🏭 character) by a POSIX sed implementation is allowed. [\f] is meant to match either backslash or f though. POSIX sed script that uses \f outside [] is not conformant. One that uses \f inside [...] would be but break with GNU sed (unless POSIXLY_CORRECT is on) where it would match a FF instead of backslash or f (so it's better to use sed 's/[\\f]// if you want to match on backslash or f. – Stéphane Chazelas Jul 31 '15 at 10:51
  • @terdon - honestly the best way to handle that kind of stuff is with shell variables. It's probably why the spec doesn't get into that stuff because it really is easy, and is kind of a no-brainer for any in-depth application anyhow. You'd do it too - if there was some command arg you were likely to reuse often in a shell script you'd put it in a variable once and then expand it when you wanted it. And so for E in a\\a b\\b e\\33 f\\f n\\n t\\t v\\v; do eval "${E%\\*}='$(printf "${E#?}'")"; done - puts them all in vars like $e and $n and so on. And there's no worry about escape support. – mikeserv Jul 31 '15 at 11:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.