Поменять местами строки в текстовом файле только там, где они содержат строки, используя sed или ed? [закрыто]

Вы буквально набираете одну из этих команд.

В Linux ваша оболочка - Bash, поэтому вам нужно получить файл settings64.sh . Для этого введите команду так же, как вы сами набрали ее в вопросе:

. /opt/Xilinx/14.7/ISE_DS/settings64.sh

Поскольку вы работаете в оболочке Bash, не создавайте файл settings64.csh . Это не для тебя.

Какое бы это ни было программное обеспечение, вы можете предложить два разных файла, один для пользователей sh -подобных оболочек (например, bash и ksh ). и один для пользователей csh -подобных оболочек (например, csh и tcsh ).

2
06.09.2017, 12:36
4 ответа

Мы можем получить желаемый эффект, поместив совпадающую строку в буфер хранения, прочитав следующую строку и распечатав ее, затем заменив буфер хранения буфером шаблонов и снова напечатав.

bash-4.3$ sed -n '/^REF\*CE/!p;/^REF\*CE/{h;n;p;x;p}' input.txt
some line here
REF*BB*106497026---------------
REF*1W*723266637---------------
REF*CE*NEW JERSEY--------------
SVC*HC^S5102*78.5*78.5**1------
another line there
0
27.01.2020, 22:39
sed -e :a -e '$!N;s/^\(REF\*CE.*\)\n\(REF\*1W.*\)/\2\n\1/;ta' -e 'P;D' <testfile.txt 
  1. Если мы не в последней строке, то добавляем следующую строку.
  2. Выполните замену в текущей строке, которая происходит только в том случае, если она соответствует substring containing pattern 1 + newline + substring containing pattern 2. Подстановка переворачивает две подстроки -. После замены вернитесь к метке :a.
  3. Если совпадений нет. Печатать пространство шаблонов как есть. Затем удалите пространство шаблона и снова запустите цикл.

Образец с некоторыми окружающими линиями...

In:

    XEF*CE*------------------------- 
    REF*CE*------------------------- 
    REF*1W*------------------------- 
    REF*2W*------------------------- 

Out:


    XEF*CE*------------------------- 
    REF*1W*------------------------- 
    REF*CE*------------------------- 
    REF*2W*------------------------- 

В более общем случае для любого шаблона1 и шаблона2

sed -e :a \
    -e "\$!N; s/^\(.*${pattern1}.*\)\n\(.*${pattern2}.*\)/\2\n\1/;ta" \
    -e 'P;D' < inputfile
2
27.01.2020, 22:39

У меня есть такое простое решение :Скажем, если вы хотите поменять местами строку с «XXXX» на строку с «YYYY» в файле, при условии, что только одна строка имеет «XXXX» и только одна имеет «YYYY»

Пример файла такой :ссс дддд
аааа фффф
ддд рррр
ддддд ХХХХ
ддддде
фффф
фффф
ффф
эээ ГГГГ
гхххх
ххххх

Моя команда 'sed' имеет вид sed 's/XXXX/ZZZZ/g;s/YYYY/XXXX/g;s/ZZZZ/YYYY/g' Помните, что строка «ZZZZ» не должна быть в файле.

-1
27.01.2020, 22:39

Общее решение для замены двух (возможно удаленных )строк, соответствующих определенным регулярным выражениям, наed:

  1. Скопируйте одну строку после второй строки.
  2. Переместите вторую строку после исходной первой строки.
  3. Удалить первую исходную строку.

Или с помощью edкоманд редактирования:

  1. /pat1/t/pat2/
  2. ?pat2?m/pat1/
  3. ?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указывает текущую позицию в файле после каждой операции.

  1. /^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
    
  2. ?^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
    
  3. ?^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

Обратите внимание, что это можно исправить, запустив то же самое во второй раз, т. е. не имеет значения, какой шаблон будет первым или вторым.

1
27.01.2020, 22:39

Теги

Похожие вопросы