crear saltos de línea después de las comas, antes del ancho de línea deseado

crear saltos de línea después de las comas, antes del ancho de línea deseado

En un archivo como:

ruler    1         2         3         4         5         6         7         8
12345678901234567890123456789012345678901234567890123456789012345678901234567890
\usage{
function(
parameter,
parameterparameter,
parameter = parameter,
parameter = p,
parameter = para,
parameter = para,
paramete = p,
parameterparameter = pa,
parameter = p,
p = pa,
param,
parameterpara = par,
paramet = par,
parameter = param,
parameterpa = param,
...
more lines

Quiero concatenar líneas desde la línea con "uso" a la línea con "..." y luego crear nuevos saltos de línea después de las comas antes del carácter 80 (columna).

Por ahora, logro romper líneas después de la enésima coma, pero no es eficiente porque en muchos casos quedan muchos espacios después de, digamos, la tercera coma. Por eso quiero que la coma antes del salto de línea esté lo más cerca posible del carácter 80.

sed -i -r '/usage/{:a;N;/\.\.\./!ba;s/\n//g}' filename.txt
sed -i 's/\(\([^,]\+,\)\{3\}\)/\1\n/g;s/\n/\n/g' filename.txt

Miré la documentación "par", "fold" y "fmt" sin éxito. "doblar" se acerca pero divide las líneas en el espacio, no en la coma:

sed -i -r '/usage/{:a;N;/\.\.\./!ba;s/\n//g}' filename.txt
fold -s filename.txt | tee filename.txt

Respuesta1

Usando awk:

$ awk '/^\\usage/,/^\.\.\./ { if (length(line $0) >= 80) { print line; line = $0 } else line = line $0; next  }; line != "" { print line; line = "" }; 1' file
         1         2         3         4         5         6         7         8
12345678901234567890123456789012345678901234567890123456789012345678901234567890
\usage{function(parameter,parameterparameter,parameter = parameter,
parameter = p,parameter = para,parameter = para,paramete = p,
parameterparameter = pa,parameter = p,p = pa,param,parameterpara = par,
paramet = par,parameter = param,parameterpa = param,...
more lines

El awkcódigo, anotado:

/^\\usage/,/^\.\.\./ {
        # This block triggers for all lines between a line
        # starting with "\usage" and another line
        # starting with "..."

        # If our saved output line and the current line together
        # is longer or equal to 80 characters, print the output
        # line and reset it to the current line.  Else, add the
        # current line to the end of the saved output line.
        if (length(line $0) >= 80) {
                print line
                line = $0
        } else
                line = line $0

        # Skip to next line of input.
        next
}

# If we get here and the saved output line is
# non-empty, then there is data to output, so
# do that.
line != "" { print line; line = "" }

# Print all input.
1

Respuesta2

Una variante perezosa, que usa perlel modo sorber de:

perl -0777 -pi -e '
  s{\\usage.*?\n\.\.\.\n}{
    ($r = $&) =~ s/\n//g;
    $r =~ s/\G.{0,79}(,|.$)\K/\n/g;
    $r
  }gse' your-file

Lo que da:

         1         2         3         4         5         6         7         8
12345678901234567890123456789012345678901234567890123456789012345678901234567890
\usage{function(parameter,parameterparameter,parameter = parameter,
parameter = p,parameter = para,parameter = para,paramete = p,
parameterparameter = pa,parameter = p,p = pa,param,parameterpara = par,
paramet = par,parameter = param,parameterpa = param,...
more lines

información relacionada