удалить конкретный текст, основанный на содержимом следующей строки

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

Вот как вы можете использовать fc и history с псевдонимами для !- как подстановки. Предположим, если вы хотите использовать ! -n (где n - цифра для nth последней использованной команды), то вы можете использовать fc и history с псевдонимом следующим образом:

  1. Использование history:

    alias xyz='echo $(history -p "! -") ; sudo $(history -p "!-n")'
    

    Примечание: Здесь !-n должно быть заключено в ' или ''.

  2. Использование fc:

    alias xyz='echo $(fc -ln -n -n) ; sudo $(fc -ln -n -n)''
    

    Примечание: здесь 1st и 2nd-n используются для указания диапазона списка истории.

Здесь я использовал echo-ing перед выполнением команды для получения эффекта !-.

1
10.10.2018, 15:26
2 ответа

Вы можете использовать sedследующим образом:

sed -e '/,$/{N; /\]/s/,[^,]*$//;}' file
987678680
123435434-
]
2345643
2345632-
]
234563
1234567654

Или согласно @steeldriver, это можно упростить в Bashследующим образом:

sed '$!N; s/,\n]//'
0
27.01.2020, 23:42

При работе с такого рода задачами (редактировать/делать что-то, если последовательные строки соответствуют определенному шаблону )самый простой способ сделать это с sed, вероятно, черезN;P;Dцикл , также известный как "скользящее окно":

sed -e '$!N;s/,\nPATTERN//;t' -e 'P;D' file

Это вводит строку Next в пространство шаблонов и безоговорочно пытается sзаменить ее в соответствии с требованием. Затем он tпроверяет, была ли замена успешной :, если да, то переходит в конец скрипта (без метки )и автоматически печатает пространство шаблона, в противном случае он Pперепечатывает и Dудаляет первую строку из пространства шаблонов и перезапускает цикл.


Другой метод GNUsed:

sed ':x /,$/{N;s/,\n]//;T x}' file

Это работает корректно, даже если запятая стоит в четной -пронумерованной строке. Пример:

printf '%s\n' 1, 2, ']' | sed ':x /,$/{N;s/,\n]//;T x}'

Выход:

1,
2

Как это работает:

В большинстве языков программирования адресные метки являются полностью пассивными --метками, обозначающими код, но никогда не изменяющими действие этого кода. Но не sed. В sedпереход к метке в начале программы фактически меняет действие кода или, скорее, позволяет избежать неявного кодаnext -строки , с которого обычно начинается sedцикл.

КомандаTest and branch if failed T xпроверяет, не сделала ли ничего предыдущая командаsubstitute , и если да, то переходит к метке :xв начале без ни печати чего-либо, ни чтения новой строки. Это означает, что любая нечетная -пронумерованная строка, выбранная с помощью append Next строки , которая не была заменена, будет повторно -просканирована, как и должно быть.


Для не-GNU sed, (, когда команда Tнедоступна и синтаксис не является разрешающим ),это должно быть более портативным:

sed ':x
/,$/{
N
s/,\n]//
t
b x
}' file
1
27.01.2020, 23:42

Теги

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