Code formatting with bash script

1.1k Views Asked by At

I would like to search through a file and find all instances where the last non-blank character is a comma and move the line below that up one. Essentially, undoing line continuations like

private static final double SOME_NUMBERS[][] = {
    {1.0, -6.032174644509064E-23},
    {-0.25, -0.25},
    {-0.16624879837036133, -2.6033824355191673E-8}
};

and transforming that to

private static final double SOME_NUMBERS[][] = {
    {1.0, -6.032174644509064E-23}, {-0.25, -0.25}, {-0.16624879837036133, -2.6033824355191673E-8}
};

Is there a good way to do this?

4

There are 4 best solutions below

2
John1024 On BEST ANSWER

As mjswartz suggests in the comments, we need a sed substitution command like s/,\n/ /g. That, however, does not work by itself because, by default, sed reads in only one line at a time. We can fix that by reading in the whole file first and then doing the substitution:

$ sed 'H;1h;$!d;x; s/,[[:blank:]]*\n[[:blank:]]*/, /g;' file
private static final double SOME_NUMBERS[][] = {
    {1.0, -6.032174644509064E-23}, {-0.25, -0.25}, {-0.16624879837036133, -2.6033824355191673E-8}
};

Because this reads in the whole file at once, this is not a good approach for huge files.

The above was tested with GNU sed.

How it works

  • H;1h;$!d;x;

    This series of commands reads in the whole file. It is probably simplest to think of this as an idiom. If you really want to know the gory details:

    • H - Append current line to hold space
    • 1h - If this is the first line, overwrite the hold space with it
    • $!d - If this is not the last line, delete pattern space and jump to the next line.
    • x - Exchange hold and pattern space to put whole file in pattern space
  • s/,[[:blank:]]*\n[[:blank:]]*/, /g

    This looks for lines that end with a comma, optionally followed by blanks, followed by a newline and replaces that, and any leading space on the following line, with a comma and a single space.

0
Gilad Merran On

I think for large files awk would be better:

awk -vRS=", *\n" -vORS=", " '1' file
0
weiweishuo On

On lua-shell, just write like this:

function nextlineup()
    vim:normal("j^y$k$pjddk")
end

vim:open("code.txt")
vim:normal("G")
while vim:k() do
    vim:normal("$") 
    if(vim.currc == string.byte(',')) nextlineup();
end

If you are not familier with vim ,this script seems a bit scary and not robust. In fact, every operation in it is precise(and much quicker, because tey are built-in functions). Since you are processing a code file, i suggest you try it.

here is a demo

0
balabhi On

Here is a perl solution.
cat file | perl -e '{$c = 0; while () { s/^\s+/ / if ($c); s/,\s*$/,/; print($_); $c = (m/,\s*$/) ? 1: 0; }}'