Všiml jsem si toho, když přidám n
na vzor pro nahrazení pomocí sed
, to se neshoduje. Příklad:
$ cat > alpha.txt
This is
a test
Please do not
be alarmed
$ sed -i'.original' 's/a testnPlease do not/not a testnBe/' alpha.txt
$ diff alpha.txt{,.original}
$ # No differences printed out
Jak to mohu zprovoznit?
Přijatá odpověď:
V nejjednodušším volání sed , má jeden řádek textu ve vzorovém prostoru, tzn. 1 řádek z n
text oddělený od vstupu. Jediný řádek v prostoru vzoru nemá n
… Proto váš regulární výraz nic nenachází.
Můžete číst více řádků do prostoru vzorů a manipulovat s věcmi překvapivě dobře, ale s větším úsilím, než je obvyklé.. Sed má sadu příkazů, které umožňují tento typ věcí... Zde je odkaz na Souhrn příkazů pro sed. Je to nejlepší, co jsem našel, a dostal mě do pohybu.
Jakmile však začnete používat mikropříkazy sed, zapomeňte na myšlenku „one-liner“. Je užitečné si to rozložit jako strukturovaný program, dokud to neucítíte... Je to překvapivě jednoduché a stejně neobvyklé. Dalo by se to považovat za „jazyk sestavy“ úprav textu.
Shrnutí:Používejte sed na jednoduché věci a možná trochu víc, ale obecně platí, že když to přesáhne práci s jedním řádkem, většina lidí dává přednost něčemu jinému...
Nechám někoho jiného, aby navrhl něco jiného.. I Opravdu si nejsem jistý, jaká by byla nejlepší volba (použil bych sed, ale to je proto, že neznám dost dobře perl.)
sed '/^a test$/{
$!{ N # append the next line when not on the last line
s/^a testnPlease do not$/not a testnBe/
# now test for a successful substitution, otherwise
#+ unpaired "a test" lines would be mis-handled
t sub-yes # branch_on_substitute (goto label :sub-yes)
:sub-not # a label (not essential; here to self document)
# if no substituion, print only the first line
P # pattern_first_line_print
D # pattern_ltrunc(line+nl)_top/cycle
:sub-yes # a label (the goto target of the 't' branch)
# fall through to final auto-pattern_print (2 lines)
}
}' alpha.txt
Zde je to stejný scénář, zhuštěný do toho, co je zjevně těžší na čtení a práci s ním, ale někteří by pochybně nazvali jednořádkovou
sed '/^a test$/{$!{N;s/^a testnPlease do not$/not a testnBe/;ty;P;D;:y}}' alpha.txt
Zde je můj příkaz „cheat-sheet“
: # label
= # line_number
a # append_text_to_stdout_after_flush
b # branch_unconditional
c # range_change
d # pattern_delete_top/cycle
D # pattern_ltrunc(line+nl)_top/cycle
g # pattern=hold
G # pattern+=nl+hold
h # hold=pattern
H # hold+=nl+pattern
i # insert_text_to_stdout_now
l # pattern_list
n # pattern_flush=nextline_continue
N # pattern+=nl+nextline
p # pattern_print
P # pattern_first_line_print
q # flush_quit
r # append_file_to_stdout_after_flush
s # substitute
t # branch_on_substitute
w # append_pattern_to_file_now
x # swap_pattern_and_hold
y # transform_chars