input.txt
파일에 다음과 같은 여러 문자열이 포함되어 있다고 가정합니다 .
[[foo>a|a]]
[[foo>b|b]]
[[foo>c|c]]
나는 다음으로 바꾸고 싶다:
:foo:`a`
:foo:`b`
:foo:`c`
나는 sed
이 결과를 사용하거나 달성 할 수 있다고 생각합니다 rg
(나는 그것을 사용한 적이 없습니다 awk
).
하지만 파일에는 다음과 같은 다른 문자열도 포함되어 있습니다.
[[foo>a|d]]
[[foo>b|e]]
[[foo>c|f]]
나는 다음으로 바꾸고 싶다:
:foo:`d <a>`
:foo:`e <b> `
:foo:`f <c>`
두 가지 다른 모드를 동시에 처리하는 방법을 모르기 때문에 모든 시도가 실패했습니다.
후자의 결과(그리고 전자의 결과)를 얻을 수 있는 몇 가지 방법을 알고 있습니까?
답변1
표준 sed
구문을 사용하십시오.
sed '
s/^\[\[\(.*\)>\(.*\)|\2\]\]$/:\1:`\2`/; t
s/^\[\[\(.*\)>\(.*\)|\(.*\)\]\]$/:\1:`\3 <\2>`/'
답변2
주변을 살펴보면 주변 문자열이 |
동일한지 확인할 수 있습니다. 예를 들어:
$ cat ip.txt
[[foo>a|d]]
[[foo>b|e]]
[[foo>c|f]]
# same as: rg -NP '\[\[([^>]+)>([^|]+)\|(?!\2])([^|]+)]]' -r ':$1:`$3 <$2>`'
$ perl -pe 's/\[\[([^>]+)>([^|]+)\|(?!\2])([^|]+)]]/:$1:`$3 <$2>`/' ip.txt
:foo:`d <a>`
:foo:`e <b>`
:foo:`f <c>`
(?!\2])
|
주변 문자열이 다른지 확인하기 위한 부정적인 예측 어설션입니다 .
두 가지를 모두 달성하려면 대체 섹션에서 플래그와 함께 Perl 코드를 사용할 수 있습니다 e
.
$ cat ip.txt
[[foo>a|a]]
[[foo>b|b]]
[[foo>c|c]]
[[foo>a|d]]
[[foo>b|e]]
[[foo>c|f]]
$ perl -pe 's/\[\[([^>]+)>([^|]+)\|([^|]+)]]/":$1:`$3" . ($2 eq $3 ? "`" : " <$2>`")/e' ip.txt
:foo:`a`
:foo:`b`
:foo:`c`
:foo:`d <a>`
:foo:`e <b>`
:foo:`f <c>`
여기서는 주변 문자열이 동일한지 여부에 따라 문자열이 선택됩니다 ($2 eq $3 ? "`" : " <$2>`")
.|
답변3
이 작업을 2~3개의 개별 부분으로 나눌 수 있을 것 같습니다. 먼저 squeeze( -s
)하고 일부 문자를 로 대체하여 tr
출력의 "개요"를 생성한 다음 a를 사용하여 sed
두 개의 문자가 일치할 때 하나와 두 문자가 일치하지 않을 때로 두 개의 별도 대체를 만듭니다.
< file tr -s '[<>|]' ':::``' | sed -E 's/(.)`\1`/`\1`/; s/([^:])`(.)`/`\2 <\1>`/'
시험:
$ cat file
[[foo>a|a]]
[[foo>b|b]]
[[foo>c|c]]
[[foo>a|d]]
[[foo>b|e]]
[[foo>c|f]]
$ <file tr -s '[<>|]' ':::``' | sed -E 's/(.)`\1`/`\1`/;s/([^:])`(.)`/`\2 <\1>`/'
:foo:`a`
:foo:`b`
:foo:`c`
:foo:`d <a>`
:foo:`e <b>`
:foo:`f <c>`
답변4
awk
주어진 두 가지 형식의 처리를 관리하는 데 사용됩니다 .
awk -F'\\[\\[|\\]\\]|>|\\|' '{
print $1, $2, "`" ($3==$4? $3 : $4" <"$3">") "`";
}' OFS=':' infile
테스트 입력:
[[foo>a|a]]
[[foo>bb|bb]]
[[foo>c|ccc]]
[[foo>aaaa|d]]
[[foo>b|ddd]]
[[foo>cccc|fff]]
산출:
:foo:`a`
:foo:`bb`
:foo:`ccc <c>`
:foo:`d <aaaa>`
:foo:`ddd <b>`
:foo:`fff <cccc>`