다음 ed
스크립트 가 주어지면
$ cat helloworld
a
hello
world
.
,n
,s,o,O,g
,n
Q
어떻게든 대화형 출력을 얻고 싶습니다.
$ ed
a
hello
world
.
,n
1 hello
2 world
,s,o,O,g
,n
1 hellO
2 wOrld
Q
$
기대보다는
$ cat helloworld | ed
1 hello
2 world
1 hellO
2 wOrld
$
아마도 타사 유틸리티를 사용하여 이것이 가능합니까? 미리 감사드립니다!
편집하다:동기 부여를 추가해야겠다고 생각했습니다. 몇 가지 샘플 편집 세션을 만들고 이를 script(1)
. 긴 편집 세션(심지어 더 나쁨)
답변1
좋아, 이리저리 고민한 후에 이것이 내가 사용할 것입니다:
awk '{ print; system("sleep 0") }' edscript | tee /dev/tty | ed
또는 다음 없이 tee
:
awk '{ print >"/dev/stderr"; print | "ed"; system("sleep 0") }' edscript
print >"/dev/stderr"
시스템에서 작동하지 않으면 를 사용할 수 있습니다 print | "cat >&2"
.
그리고 gnu sed
:
sed -u -n -e 'p;w /dev/stderr' -e 's|.*||e' edscript | ed
똑같이 효과적인 또 다른 방법:
사용 split
을 분할하는 것입니다.스크립트 편집각 줄:
split -l1 edscript
xaa
그러면 ... xab
작동하는 것과 같은 결과가 나올 것입니다 xah
.
그런 다음 다음과 같은 부품을 사용할 수 있습니다.
for i in x*; do awk '{ print >"/dev/stderr"; print }' $i; done | ed
또는
for i in x*; do sed -n -e 'p;w /dev/stderr' $i; done | ed
예상된 결과를 얻으려면. 그럼 당신은 rm x*
...
답변2
사용자가 명령을 입력하고 응답을 기다리는 대화형 터미널 세션을 시뮬레이션하려는 것 같습니다(또는 목표가 다음과 같다고 가정) ed
.때때로응답을 기다린 후) 다른 명령 등을 입력하십시오. 이를 수행하기 위한 스크립트 를 작성할 수 있지만 expect
각 줄 사이에 잠시 멈춤을 두고 터미널과 대상 프로세스에 한 번에 한 줄씩 보내는 것만으로도 충분할 수 있습니다.
$ while IFS= read -r line
do
printf '%s\n' "$line" >/dev/tty
printf '%s\n' "$line"
sleep 0.5
done < helloworld | ed
a
hello
world
.
,n
1 hello
2 world
,s,o,O,g
,n
1 hellO
2 wOrld
Q
입력과 출력을 더 잘 구별하기 위해 줄에 색상이나 기타 강조 표시를 추가할 수 있습니다. 또는 이 특별한 경우에는echo "$line" >/dev/tty
(명령)에서 프롬프트 문자를 활성화하여 각 명령 앞에 a가 표시되도록 할 수 있습니다.ed
P
*
ed
답변3
내가 뭔가를 했는데... 복잡한 일이었어. 나는 최근 ex
에 조사해 왔고 ed
- 나도 별로 잘하지 못하지만 - 이것은 더 깊이 탐구할 수 있는 기회가 되었습니다. 먼저 ed
스크립트를 구문 분석하고 ed
스트림 내부에 전달합니다.
b='[:blank:]'
sed -e 'h;/\n/!i\' -e 0i -e 's/^\(.*[^\]\)*\(\\\\\)*\\$//;tn'"
/^\n*\([0-9;$,.$b]*[gGvV].*\\\\\n[$b]*\)*\([0-9,$.;${b}]*[aic][$b]*\)\
\(\n\(.*\)\n\.\)*\(\n.*\)*$/{ s//\4/;:n" -e 'G;//{N;D
};g;s//\1\2/;l;x;s//\4/;l;H;s/.*/./;a\' -e '.
};l;g;i\' -e .\\ -e 1,.p\\ -e u <ed_script | ed
예전만큼 복잡하지 않습니다. 이제 거의 모든 복잡성이 두 줄에 걸쳐 있는 단일 정규식에 집중되어 있습니다. 이 긴 정규식은 전체 스크립트의 거의 모든 테스트를 처리합니다.
내가 아는 한, 아이디어는 당신이 도달할 수 있다는 것입니다끼워 넣다a
pend, i
nsert 또는 c
hange 명령 중 하나를 사용하는 모드끼워 넣다그런 다음 패턴은 .
문자 그대로 점으로만 구성된 다음 줄로 모든 입력을 가져옵니다. 여러 줄에 걸쳐 있는 다른 연속 명령( , 또는 포함된 시퀀스라도 ) G
은 후행 백슬래시 와 함께 다음 줄로 계속되어야 합니다 . 하지만 평소와 같이 백슬래시는 해당 컨텍스트에서 자체적으로 이스케이프됩니다.g
V
v
\
\
따라서 내가 틀렸을 가능성이 충분히 있지만,생각하다이것은 모든 상황을 처리합니다. 일련의 [aic]
... 포인트 .
와 일치하지 않는 각 입력 라인 에 대해 sed
다음과 같은 일련의 명령을 삽입하십시오.
0i
command-line$
.
1,.p
u
... 명시적인 ook 의 ed
삽입을 나타냅니다.i
l
(작성된 대로 sed
)자체 순서에 따라 p
인쇄하고 마지막으로 u
모든 작업을 수행합니다. 편집을 마치고 인쇄하고 반전하는 매우 편리한 결과를 얻습니다.그리고단일 작업으로 마지막 주소를 복구합니다.
아래 기준을 충족하시는 분들을 대상으로하다좀 더 복잡한 일련의 후행 백슬래시 [aic]
와 일치합니다. .
이러한 경우 sed
시리즈의 끝에 도달할 때까지 재귀적으로 끌어온 다음 l
작업이 수행됩니다. [aic]
, 및 실제 텍스트 입력을 별도의 인쇄물로 분리하는 데 주의를 기울였습니다 .
. 각 유형에는 고유한 ook이 있으므로 l
텍스트 입력이 가능한 한 함께 연결됩니다.(기본적으로 ook 출력은 sed
80자에서 중단됩니다 l
.).
보여드리는 게 더 쉬울 것 같았어요. 아래에서 알 수 있습니다 ?
. 이는 이전에 제공된 명령이 유효한 명령이 아니었기 때문에 발생합니다 . - 손상된 입력 g
때문이 아닙니다.sed
(나는 희망). 다음은 예제 데이터세트의 수정된 버전의 출력입니다.
g \\\n a$
hello\nworld\\\n\n 0a\n world\\\nworld\nworld$
.$
?
,n$
1 hello
2 world\
3
4 0a
5 world\
6 world
7 world
,s,o,O,g$
4$
0a
.,$n$
4 0a
5 wOrld\
6 wOrld
7 wOrld
,s,$,\\\n\\\n\\\\$
\
,n$
1 hellO
2
3 \
4 wOrld\
5
6 \
7
8
9 \
10 0a
11
12 \
13 wOrld\
14
15 \
16 wOrld
17
18 \
19 wOrld
20
21 \
Q$