Al momento ho file che contengono sezioni come questa
code statement1 code statement2 # BEGIN SOMENAME some code some other code # END SOMENAME code statement n +1 code statement n +1
Quello che voglio fare è commentare ciò che si trova tra “# BEGIN SOMENAME” e “# END”, in modo che alla fine assomigli a questo
code statement1 code statement2 # BEGIN SOMENAME # some code # some other code # END SOMENAME code statement n +1 code statement n +1
Posso ottenere questo risultato con awk o sed? e posso invertirlo facilmente ?, quindi solo unoperazione, che “commenta” di nuovo?
Quello che voglio evitare di commettere errori, quindi se le righe sono già commentate dovrebbe essere lasciato in pace. Anche in “comment in” non dovrebbe provare a fare qualcosa se le linee tra end e begin non iniziano con un “#”.
Lho provato per diverse ore, senza successo.
Trovato una possibile soluzione:
awk " BEGIN { i=0; line_with_no_comment_found=0 } /^# END/ { m=0; if ( line_with_no_comment_found == 1 ) { for (var in a) print "# "a[var] } else { for (var in a) print a[var] } delete a; i=0; line_with_no_comment_found=0; } /^# / { if (m==0) { print } else { a[i++]=$0; } } !/^# / { if (m==0) { print } else { a[i++]=$0; line_with_no_comment_found=1} } /^# BEGIN ([a-zA-Z_])([1-9][0-9]*)*/ {m=1;} END { } "<<EOF
Commenti
- forse, perché questo vecchio codice ha errori del genere più righe di inizio (copia / incolla bug …?) dopo laltro, e devi solo ignorare il primo o a volte linizio inizia e il file finisce …. i ' preferirei non pubblicare questo script, ora è completamente rotto …
- hai ragione. ha aggiunto questo alle sfide. Scusa mi sono stancato, e sembra sempre che quando ho trovato una soluzione parziale, tutte le altre cose smettono di funzionare
Risposta
Questo script funziona per me. Lho testato in GNU Awk 4.0.1, ma dovrebbe funzionare anche in Nawk.
awk "BEGIN { # action=0: uncomment # action=1: comment action=0 in_optional_code_block=0 } { if ($0 ~ /^# BEGIN/) { in_optional_code_block=1 } else if ($0 ~ /^# END/) { in_optional_code_block=0 } else if (in_optional_code_block) { if (action) { if ($0 !~ /^#/) { $0 = "# " $0 } } else { if ($0 ~ /^#/) { sub(/^# ?/, "") } } } } 1"
Ho anche scritto un piccolo script di shell di accompagnamento:
#!/usr/bin/env sh syntax_error() { echo "Usage: `basename \"$0\"` [comment|uncomment] file" >&2 exit 1 } case "$1" in 0|uncomment) action=0; ;; 1|comment) action=1; ;; *) syntax_error; ;; esac shift if [ -z "$@" ]; then syntax_error; fi awk "BEGIN { action="$action" in_optional_code_block=0 } { if ($0 ~ /^# BEGIN/) { in_optional_code_block=1 } else if ($0 ~ /^# END/) { in_optional_code_block=0 } else if (in_optional_code_block) { if (action) { if ($0 !~ /^#/) { $0 = "# " $0 } } else { if ($0 ~ /^#/) { sub(/^# ?/, "") } } } } 1" "$@" > "[email protected]" if [ $? -eq 0 ]; then mv "[email protected]" "$@"; fi
(Se hai GNU Awk 4.1.0 o successivo, puoi usare il flag -i invece della costruzione del movimento alla fine.)
Commenti
- @Mandragor Se SOMENAME nei commenti di apertura e di chiusura deve corrispondere, fammi un messaggio.