7

I have many little poems to edit like this:

Io avevo due sorelle,
una bionda e l’altra mora,
tutte e due leggiadre e belle
e gentil come l’aurora.
ma la bionda mi è sparita,
se ne è andata all’altra vita.
mi hanno detto che lassù
più risplende il suo bel viso
dove è gioia ed è sorriso
ma non tornerà mai più.
e la mora sta lontana,
nella terra pascoliana.
colgo e bacio il primo fiore:
il pensier quel bacio porta
su la viva e su la morta,
tutte e due lo stesso amore.

Italian grammar rules prescribe uppercase on first letter when a verse starts after that in previous verse there is a period. So it should be (see uppercase letter after period at line 5, for Instance)

Io avevo due sorelle,
una bionda e l’altra mora,
tutte e due leggiadre e belle
e gentil come l’aurora.
Ma la bionda mi è sparita,
se ne è andata all’altra vita.
Mi hanno detto che lassù
più risplende il suo bel viso
dove è gioia ed è sorriso
ma non tornerà mai più.
E la mora sta lontana,
nella terra pascoliana.
Colgo e bacio il primo fiore:
il pensier quel bacio porta
su la viva e su la morta,
tutte e due lo stesso amore.

I'm in trouble to do this with sed, how it can be solved? Of you know more proper ways than sed, I'm interested too

0

6 Answers 6

9

GNU sed which has a uppercase feature \U

sed -e '
  $!N
  s/\.\n./\U&/
  P;D
' file
8

Using Perl:

perl -00 -pe 's/\.\n./\U$&/g' file

This reads the file a paragraph at a time (a paragraph is delimited by at least one empty line), and upper-cases any character occurring after a dot and a newline character.

7
printf '%s\n' 'g/\.$/+1s/./\u&/' '%p' | ex file
  • g/\.$/ selects all lines with a trailing period.

  • +1s Applies the following substitute command on the next line to each selected.

  • \u in the replacement slot uppercases the next character and & is a meta-character for "whatever was matched by the regex".

  • %p prints all the resulting lines.

Notes

  • The command outputs the expected result in the standard output. To actually edit the file, use the "write and exit" command instead:

    printf '%s\n' 'g/\.$/+1s/./\u&/' x | ex file
    
  • The /\.$/ regex won't catch lines with blank spaces after a final period. To tackle that case, use /\. *$/ instead.

0
6

Using any awk in any shell on every Unix box:

$ awk 'prev ~ /\.$/{$0=toupper(substr($0,1,1)) substr($0,2)} {prev=$0} 1' file
Io avevo due sorelle,
una bionda e l’altra mora,
tutte e due leggiadre e belle
e gentil come l’aurora.
Ma la bionda mi è sparita,
se ne è andata all’altra vita.
Mi hanno detto che lassù
più risplende il suo bel viso
dove è gioia ed è sorriso
ma non tornerà mai più.
E la mora sta lontana,
nella terra pascoliana.
Colgo e bacio il primo fiore:
il pensier quel bacio porta
su la viva e su la morta,
tutte e due lo stesso amore.
2

Using sed

$ sed '/\.$/{n;s/^[a-z]/\U&/}' input_file
Io avevo due sorelle,
una bionda e l’altra mora,
tutte e due leggiadre e belle
e gentil come l’aurora.
Ma la bionda mi è sparita,
se ne è andata all’altra vita.
Mi hanno detto che lassù
più risplende il suo bel viso
dove è gioia ed è sorriso
ma non tornerà mai più.
E la mora sta lontana,
nella terra pascoliana.
Colgo e bacio il primo fiore:
il pensier quel bacio porta
su la viva e su la morta,
tutte e due lo stesso amore.
1
  • 6
    This is flawed. What if there are consecutive lines ending with dots? Your sed code will alter every other line. In other words: the line you read with n may end with a dot, but the code does not take it into account. Jan 5 at 4:51
2

Using Raku (formerly known as Perl_6)

raku -e 'S:g/ \. $$ \n ^^ <(\w)> /{$/.uc}/.put given lines.join("\n");'    

Sample Input:

"Le due sorelle"
(di Giuseppe Geri Gavinana)

Io avevo due sorelle,
una bionda e l’altra mora,
tutte e due leggiadre e belle
e gentil come l’aurora.
ma la bionda mi è sparita,
se ne è andata all’altra vita.
mi hanno detto che lassù
più risplende il suo bel viso
dove è gioia ed è sorriso
ma non tornerà mai più.
e la mora sta lontana,
nella terra pascoliana.
colgo e bacio il primo fiore:
il pensier quel bacio porta
su la viva e su la morta,
tutte e due lo stesso amore.

Sample Output:

"Le due sorelle"
(di Giuseppe Geri Gavinana)

Io avevo due sorelle,
una bionda e l’altra mora,
tutte e due leggiadre e belle
e gentil come l’aurora.
Ma la bionda mi è sparita,
se ne è andata all’altra vita.
Mi hanno detto che lassù
più risplende il suo bel viso
dove è gioia ed è sorriso
ma non tornerà mai più.
E la mora sta lontana,
nella terra pascoliana.
Colgo e bacio il primo fiore:
il pensier quel bacio porta
su la viva e su la morta,
tutte e due lo stesso amore.

Above is an answer coded in Raku, a member of the Perl family of programming languages. A few niceties of Raku include a new, more powerful regex engine, as well as graceful handling of Unicode built-in.

Briefly, lines are read lazily and (because the desired recognition sequence spans different lines), they are join-ed with \n to reconstruct the original input. Raku's non-destructive S/// idiom is then used to recognize the first ^^ beginning-of-line \w character following a three-'atom' \. literal dot, $$ end-of-line, \n newline sequence. Note regex 'atoms' can be freely separated by whitespace in the recognition (left) half of the S/// operator. From here Raku's <(...)> match operator is used to drop everything from the $/ match object variable outside of \w. In the replacement the $/.uc match object variable is uppercased, replacing the (lowercase) /w beginning-of-line character.

A few notes of interest, in true Perlish TMTOWTDI-spirit, the Raku code above can be written as follows, which returns the same output as above:

raku -e 'lines.join("\n").subst(:global, / \. $$ \n ^^ <(\w)> /, {$/.uc}).put;'

And if you just want to look at the recognition sequence before replacement, you can abstract out the $/ match variable and say it (useful for refining your regex code). Below, Raku recognizes four (4) individual, beginning-of-line characters, poised for replacement:

raku -e 'say $/ given lines.join("\n").subst(:global, / \. $$ \n ^^ <(\w)> /, {$/.uc});'  file
(「m」 「m」 「e」 「c」)

Note: a rough (working) Raku translation of the Perl5 code posted by @they might be:

raku -e 'for lines.join("\n") {S:g/\.\n./{$/.uc}/.put};'  

https://docs.raku.org/language/operators#S///_non-destructive_substitution
https://raku.org

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.