다음 패턴에 따라 파일의 문자열을 바꾸고 싶습니다.
<<key q>>
→<kbd>q</kbd>
<<key Ctrl q>>
→<kbd>Ctrl</kbd>+<kbd>q</kbd>
<<key Ctrl Shift Alt q>>
→<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>q</kbd>
업데이트: 파일에는 추가 텍스트도 포함되어 있습니다. 예: Press <<key Ctrl q>> to quit.
이 문제를 해결하기 위해 찾을 수 있는 가장 좋은 해결책은 sed
호출할 1, 2, 3, 4 키에 대해 별도의 스크립트를 사용하는 것입니다.
sed -i -E \
-e 's|<<key ([^ ]+)>>|<kbd>\1</kbd>|g'
-e 's|<<key ([^ ]+) ([^ ]+)>>|<kbd>\1</kbd>+<kbd>\2</kbd>|g' \
-e 's|<<key ([^ ]+) ([^ ]+) ([^ ]+)>>|<kbd>\1</kbd>+<kbd>\2</kbd>+<kbd>\3</kbd>|g' \
-e 's|<<key ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)>>|<kbd>\1</kbd>+<kbd>\2</kbd>+<kbd>\3</kbd>+<kbd>\4</kbd>|g' \
file.txt
분명히 이것은 5개 이상의 키를 포함하는 매크로에서는 실패할 것입니다.
더 일반적인 솔루션이 있습니까?N열쇠? 에 국한되지 않고 sed
구조적 정규식(sregx) 그러나 그것을 수행하는 방법을 찾을 수 없습니다.
답변1
나는 그러한 작업을 수행하기 위해 Perl을 사용할 것입니다.
#!/bin/perl
while(<>) {
if (/<<key (.*?)>>/) {
my $pattern_with_keys = $1;
my @keys = split / /, $pattern_with_keys ;
my @kbd_keys = map {"<kbd>$_</kbd>"} @keys;
print join('+', @kbd_keys), "\n";
}
}
그것을 실행 perl script.pl < source_file.txt
하고 즐기십시오.
답변2
- 한 번에 하나씩 교체하십시오.
- 새로운 교체가 완료되지 않을 때까지 이 작업을 반복합니다.
- 정크를 제거하십시오.
이와 같이:
sed -E ':start s|(<<key[^>]*) ([^>]*)>>|\1>>+<kbd>\2</kbd>|g; t start; s|<<key>>\+||g'
어디:
:start
라벨입니다.s|(<<key[^>]*) ([^>]*)>>|\1>>+<kbd>\2</kbd>|g
이 되다.<<key Ctrl Shift Alt q>>
<<key Ctrl Shift Alt>>+<kbd>q</kbd>
t start
s
방금 교체한 것이 있는 경우에만 태그로 이동하십시오 .- ...
<<key Ctrl Shift Alt>>+<kbd>q</kbd>
가 되고
<<key Ctrl Shift>>+<kbd>Alt</kbd>+<kbd>q</kbd>
, 그러면
<<key Ctrl>>+<kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>q</kbd>
마침내
<<key>>+<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>q</kbd>
. 다음 반복에서는s
아무것도 대체되지 않으므로 (<<key>>
공간이 없기 때문에 일치하지 않음) 작업t
이 필요하지 않습니다. s|<<key>>\+||g
잔여물을 제거하십시오.
참고: ( [^>]*
대 상대 .*
)는 <<key …>>
동일한 줄에 있는 여러 조각 간의 일치를 방지합니다.