Использовать sed для копирования в предыдущую строку

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

Если вы находитесь в командной строке: gvfs-open . или gnome-open . откроют его в браузере настроенных папок.

. Команда sed не будет отражать поведение DM, в том числе такие вещи, как fiddy stuff убегает и цитирует, где вам действительно не хотелось бы альтернативного поведения. Это не командная строка, но она проверяет все. Я также нашел установку Terminal=true полезной для отладки.

2
задан 9 January 2018 в 22:19

8 ответов

Я подозреваю, что sed не для этого (и другие могут знать, как сделать это намного лучше с sed), но здесь идет:

$ sed '2,$ s/.$/&,&/' file | sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta' | sed '$d'
A,p,q
B,q,r
C,r,s

Примечания [!d1 ]

sed '2,$ s/.$/&,&/' означает дублирование последнего символа на всех, кроме первой строки, добавление запятой:

2,$ со второй строки вперед s/old/new/ заменить old на new [ f12] последний символ & совпадающий шаблон

sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta;' означает взять последний символ из каждой строки после первого и вставить его в конец предыдущей строки:

] 2,$ со второй строки и далее :a label: выполните здесь s/old/new/ замените old на new N, прочитав следующую строку в пространство шаблонов, чтобы мы могли использовать \n для представления новых строк в шаблоне .$ последнего символа ? ноль или одного из предыдущего символа & сопоставленного шаблона \1 ссылка на сохраненный паттерн ta, если последняя команда s была успешной, перейдите к :a и выполните цикл снова $d удалите последнюю строку

Если ваш файл нет t есть только отдельные символы между запятыми, вы не сможете использовать очень простое регулярное выражение выше. Вот версия, которая работает, если файл разделен запятой. Например, данный

January,apple
February,pear
March,kiwi
April,mango

Вы могли бы это сделать, что также работает, если есть только один символ, конечно

$ sed '2,$ s/[^,]*$/&,&/' file | sed -r ':a;N;s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/;ta;' | sed '$d'
January,apple,pear
February,pear,kiwi
March,kiwi,mango

sed скрипты могут быть записаны на нескольких линий. Я не могу утверждать, что это значительно улучшает читаемость;) но оно может быть более портативным, поскольку существуют ограничения на использование ; в версиях, отличных от GNU sed:

sed '2,$ s/[^,]*$/&,&/' file |
sed -r '{:a
          N
          s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/
          ta}' |
sed '$d'

[^,]* означает ноль или более символов, которые не являются запятыми.

3
ответ дан 22 May 2018 в 15:39
  • 1
    Вы можете сделать это в одном вызове, я думаю: sed -nr '$!{:a;N;s/(.*)\n(.*)(,[^,]*)/\1\3\n\2\3/;P;D;ba;}' – steeldriver 10 January 2018 в 07:19
  • 2
    @steeldriver потрясающий! Я смеюсь, потому что мне не приходило в голову повторно использовать \3 и т. Д. Вместо того, чтобы сначала копировать шаблон! Спасибо, что научились цитировать адрес. Я думаю, вы должны пойти дальше и опубликовать свой ответ :) – Zanna 10 January 2018 в 15:37

Я подозреваю, что sed не для этого (и другие могут знать, как сделать это намного лучше с sed), но здесь идет:

$ sed '2,$ s/.$/&,&/' file | sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta' | sed '$d' A,p,q B,q,r C,r,s

Примечания

sed '2,$ s/.$/&,&/' означает дублирование последнего символа на всех, кроме первой строки, добавление запятой:

2,$ со второй строки вперед s/old/new/ заменить old на new .$ последний символ & совпадающий шаблон

sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta;' означает взять последний символ из каждой строки после первого и вставить его в конец предыдущей строки:

] 2,$ со второй строки и далее :a label: выполните здесь s/old/new/ замените old на new N, прочитав следующую строку в пространство шаблонов, чтобы мы могли использовать \n для представления новых строк в шаблоне .$ последнего символа ? ноль или одного из предыдущего символа & сопоставленного шаблона \1 ссылка на сохраненный паттерн ta, если последняя команда s была успешной, перейдите к :a и выполните цикл снова $d удалите последнюю строку

Если ваш файл нет t есть только отдельные символы между запятыми, вы не сможете использовать очень простое регулярное выражение выше. Вот версия, которая работает, если файл разделен запятой. Например, данный

January,apple February,pear March,kiwi April,mango

Вы могли бы это сделать, что также работает, если есть только один символ, конечно

$ sed '2,$ s/[^,]*$/&,&/' file | sed -r ':a;N;s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/;ta;' | sed '$d' January,apple,pear February,pear,kiwi March,kiwi,mango

sed скрипты могут быть записаны на нескольких линий. Я не могу утверждать, что это значительно улучшает читаемость;) но оно может быть более портативным, поскольку существуют ограничения на использование ; в версиях, отличных от GNU sed:

sed '2,$ s/[^,]*$/&,&/' file | sed -r '{:a N s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/ ta}' | sed '$d'

[^,]* означает ноль или более символов, которые не являются запятыми.

3
ответ дан 17 July 2018 в 23:31

Я подозреваю, что sed не для этого (и другие могут знать, как сделать это намного лучше с sed), но здесь идет:

$ sed '2,$ s/.$/&,&/' file | sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta' | sed '$d' A,p,q B,q,r C,r,s

Примечания

sed '2,$ s/.$/&,&/' означает дублирование последнего символа на всех, кроме первой строки, добавление запятой:

2,$ со второй строки вперед s/old/new/ заменить old на new .$ последний символ & совпадающий шаблон

sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta;' означает взять последний символ из каждой строки после первого и вставить его в конец предыдущей строки:

] 2,$ со второй строки и далее :a label: выполните здесь s/old/new/ замените old на new N, прочитав следующую строку в пространство шаблонов, чтобы мы могли использовать \n для представления новых строк в шаблоне .$ последнего символа ? ноль или одного из предыдущего символа & сопоставленного шаблона \1 ссылка на сохраненный паттерн ta, если последняя команда s была успешной, перейдите к :a и выполните цикл снова $d удалите последнюю строку

Если ваш файл нет t есть только отдельные символы между запятыми, вы не сможете использовать очень простое регулярное выражение выше. Вот версия, которая работает, если файл разделен запятой. Например, данный

January,apple February,pear March,kiwi April,mango

Вы могли бы это сделать, что также работает, если есть только один символ, конечно

$ sed '2,$ s/[^,]*$/&,&/' file | sed -r ':a;N;s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/;ta;' | sed '$d' January,apple,pear February,pear,kiwi March,kiwi,mango

sed скрипты могут быть записаны на нескольких линий. Я не могу утверждать, что это значительно улучшает читаемость;) но оно может быть более портативным, поскольку существуют ограничения на использование ; в версиях, отличных от GNU sed:

sed '2,$ s/[^,]*$/&,&/' file | sed -r '{:a N s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/ ta}' | sed '$d'

[^,]* означает ноль или более символов, которые не являются запятыми.

3
ответ дан 24 July 2018 в 14:01

Я подозреваю, что sed не для этого (и другие могут знать, как сделать это намного лучше с sed), но здесь идет:

$ sed '2,$ s/.$/&,&/' file | sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta' | sed '$d' A,p,q B,q,r C,r,s

Примечания

sed '2,$ s/.$/&,&/' означает дублирование последнего символа на всех, кроме первой строки, добавление запятой:

2,$ со второй строки вперед s/old/new/ заменить old на new .$ последний символ & совпадающий шаблон

sed -r ':a;N;s/\n(.)(,?.?)(,.)$/\3\n\1\2/;ta;' означает взять последний символ из каждой строки после первого и вставить его в конец предыдущей строки:

] 2,$ со второй строки и далее :a label: выполните здесь s/old/new/ замените old на new N, прочитав следующую строку в пространство шаблонов, чтобы мы могли использовать \n для представления новых строк в шаблоне .$ последнего символа ? ноль или одного из предыдущего символа & сопоставленного шаблона \1 ссылка на сохраненный паттерн ta, если последняя команда s была успешной, перейдите к :a и выполните цикл снова $d удалите последнюю строку

Если ваш файл нет t есть только отдельные символы между запятыми, вы не сможете использовать очень простое регулярное выражение выше. Вот версия, которая работает, если файл разделен запятой. Например, данный

January,apple February,pear March,kiwi April,mango

Вы могли бы это сделать, что также работает, если есть только один символ, конечно

$ sed '2,$ s/[^,]*$/&,&/' file | sed -r ':a;N;s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/;ta;' | sed '$d' January,apple,pear February,pear,kiwi March,kiwi,mango

sed скрипты могут быть записаны на нескольких линий. Я не могу утверждать, что это значительно улучшает читаемость;) но оно может быть более портативным, поскольку существуют ограничения на использование ; в версиях, отличных от GNU sed:

sed '2,$ s/[^,]*$/&,&/' file | sed -r '{:a N s/\n([^,]*)(,?[^,]*)(,[^,]*)$/\3\n\1\2/ ta}' | sed '$d'

[^,]* означает ноль или более символов, которые не являются запятыми.

3
ответ дан 24 July 2018 в 17:03

Вот как это сделать в одном вызове sed, я думаю:

sed -nE '$!{:a;N;s/(.*)\n(.*)(,[^,]*$)/\1\3\n\2\3/;P;D;ba;}' file
A,p,q
B,q,r
C,r,s

Пояснение

Структура :a;N;...P;D;ba по существу поддерживает буфер с двумя строками, внутри которого мы можем разделить поля и скопировать / переместить группы символов вокруг:

$!{                                   # For any line except the last
  :a                                  # Enter a loop:
  N                                   # Append the following line, after a newline  
  s/(.*)\n(.*)(,[^,]*)$/\1\3\n\2\3/   # Capture (1) up to the newline, 
                                      # (2) from the newline to the last comma, 
                                      # and (3) everything else into groups and 
                                      # copy group 3 before the newline
  P                                   # Print everything up to the newline
  D                                   # Delete everything up to the newline, 
                                      # ready for the next iteration
  ba
}

Обратите внимание, что использование расширенного регулярного выражения -E (или -r) не является требованием - оно просто уменьшает сумму избежать этого.

1
ответ дан 22 May 2018 в 15:39

Вот как это сделать в одном вызове sed, я думаю:

sed -nE '$!{:a;N;s/(.*)\n(.*)(,[^,]*$)/\1\3\n\2\3/;P;D;ba;}' file A,p,q B,q,r C,r,s

Пояснение

Структура :a;N;...P;D;ba по существу поддерживает буфер с двумя строками, внутри которого мы можем разделить поля и скопировать / переместить группы символов вокруг:

$!{ # For any line except the last :a # Enter a loop: N # Append the following line, after a newline s/(.*)\n(.*)(,[^,]*)$/\1\3\n\2\3/ # Capture (1) up to the newline, # (2) from the newline to the last comma, # and (3) everything else into groups and # copy group 3 before the newline P # Print everything up to the newline D # Delete everything up to the newline, # ready for the next iteration ba }

Обратите внимание, что использование расширенного регулярного выражения -E (или -r) не является требованием - оно просто уменьшает сумму избежать этого.

1
ответ дан 17 July 2018 в 23:31

Вот как это сделать в одном вызове sed, я думаю:

sed -nE '$!{:a;N;s/(.*)\n(.*)(,[^,]*$)/\1\3\n\2\3/;P;D;ba;}' file A,p,q B,q,r C,r,s

Пояснение

Структура :a;N;...P;D;ba по существу поддерживает буфер с двумя строками, внутри которого мы можем разделить поля и скопировать / переместить группы символов вокруг:

$!{ # For any line except the last :a # Enter a loop: N # Append the following line, after a newline s/(.*)\n(.*)(,[^,]*)$/\1\3\n\2\3/ # Capture (1) up to the newline, # (2) from the newline to the last comma, # and (3) everything else into groups and # copy group 3 before the newline P # Print everything up to the newline D # Delete everything up to the newline, # ready for the next iteration ba }

Обратите внимание, что использование расширенного регулярного выражения -E (или -r) не является требованием - оно просто уменьшает сумму избежать этого.

1
ответ дан 24 July 2018 в 14:01

Вот как это сделать в одном вызове sed, я думаю:

sed -nE '$!{:a;N;s/(.*)\n(.*)(,[^,]*$)/\1\3\n\2\3/;P;D;ba;}' file A,p,q B,q,r C,r,s

Пояснение

Структура :a;N;...P;D;ba по существу поддерживает буфер с двумя строками, внутри которого мы можем разделить поля и скопировать / переместить группы символов вокруг:

$!{ # For any line except the last :a # Enter a loop: N # Append the following line, after a newline s/(.*)\n(.*)(,[^,]*)$/\1\3\n\2\3/ # Capture (1) up to the newline, # (2) from the newline to the last comma, # and (3) everything else into groups and # copy group 3 before the newline P # Print everything up to the newline D # Delete everything up to the newline, # ready for the next iteration ba }

Обратите внимание, что использование расширенного регулярного выражения -E (или -r) не является требованием - оно просто уменьшает сумму избежать этого.

1
ответ дан 24 July 2018 в 17:03

Другие вопросы по тегам:

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