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 awk
có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 perl
el 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