Общее решение для замены двух (возможно удаленных )строк, соответствующих определенным регулярным выражениям, наed
:
Или с помощью ed
команд редактирования:
/pat1/t/pat2/
?pat2?m/pat1/
?pat1?d
Пример с файлом
CLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7
AMT*AU*489.8
REF*6R*00000000002
DTM*472*20160528
CAS*OA*23*306.01
CAS*PR*2*82.29
SVC*HC:99212:25*489.8*101.5**1
AMT*B6*411.43
, в котором мы хотели бы поменять местами первую строку AMT
со второй строкой CAS
. pat1
будет ^AMT\*AU
и pat2
будет ^CAS\*PR
. Обратите внимание, что нам нужно экранировать *
, чтобы он обрабатывался буквально в регулярном выражении.
Я аннотировал приведенные ниже изменения, чтобы их было легче увидеть.XXX
указывает текущую позицию в файле после каждой операции.
/^AMT\*AU/t/^CAS\*PR/
производит
CLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7
AMT*AU*489.8 <-- Line copied *from* here
REF*6R*00000000002
DTM*472*20160528
CAS*OA*23*306.01
CAS*PR*2*82.29
AMT*AU*489.8 <-- Line copied *to* here (XXX)
SVC*HC:99212:25*489.8*101.5**1
AMT*B6*411.43
?^CAS\*PR?m/^AMT\*AU/
производит
CLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7
AMT*AU*489.8
CAS*PR*2*82.29 <-- line moved here (XXX)
REF*6R*00000000002
DTM*472*20160528
CAS*OA*23*306.01
AMT*AU*489.8 <-- line previous to this deleted
SVC*HC:99212:25*489.8*101.5**1
AMT*B6*411.43
?^AMT\*AU?d
производит
CLP*815900102*2*489.8*101.5*82.29*13*PVJLS03YP0000*13*7
CAS*PR*2*82.29 <-- the line before this was removed (XXX)
REF*6R*00000000002
DTM*472*20160528
CAS*OA*23*306.01
AMT*AU*489.8
SVC*HC:99212:25*489.8*101.5**1
AMT*B6*411.43
В качестве простого -к -помните «один -вкладыш»:
pat1='^AMT\*AU'; pat2='^CAS\*PR'; printf '/%s/t/%s/\n?%s?m/%s/\n?%s?d\nwq\n' "$pat1" "$pat2" "$pat2" "$pat1" "$pat1" | ed -s file
Обратите внимание, что это можно исправить, запустив то же самое во второй раз, т. е. не имеет значения, какой шаблон будет первым или вторым.
Поведение timeout
отличается, когда он запускается из сценария оболочки. Опция --foreground
вызывает «интерактивное» поведение по умолчанию, даже при запуске из скрипта. Из справочной страницы:
--foreground
when not running timeout directly from a shell prompt, allow COMMAND to
read from the TTY and get TTY signals; in this mode, children of
COMMAND will not be timed out
И watch
должен писать в терминал, чтобы выполнять все свои причудливые трюки с ANSI.
Если вы хотите увидеть это в действии, попробуйте следующее:
$ script -c 'timeout --foreground 5s watch -n 1 ps'
$ less typescript