Удаление нескольких экземпляров строки в строке с помощью sed

У меня есть большой файл с разделителями табуляции, в котором я хотел бы сохранить только определенную строку (GO:#######), которая появляется несколько (и переменных) раз в каждой строке, а также пустые строки, содержащие точку. Когда я использую SED для замены всех строк, отличных от GO, он удаляет всю середину строки. Как предотвратить это?

Команда SED, которую я использую, и другие варианты

sed -r 's/\t`.+`\t//g' file1.txt > file2.txt

Что у меня есть

GO:1234567    `text1`moretext`    GO:5373845    `diff`text`     GO:5438534     `text`text
.
GO:3333333     `txt`text`    GO:5553535    `misc`text
.
.

Что бы я хотел

GO:1234567    GO:5373845    GO:5438534
.
GO:3333333    GO:5553535
.
.

Что я получаю

GO:1234567    GO:5438534     `text`text
.
GO:3333333    GO:5553535    `misc`text
.
.

Это очень странно, вывод вашего кода должен был быть GO:1234567 GO:5438534 text. Я не могу воспроизвести ваш вывод.

KamilCuk 10.01.2023 22:06
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Laravel - это мощный PHP-фреймворк, используемый для создания масштабируемых и надежных веб-приложений. Одним из преимуществ Laravel является его...
Что такое двойные вопросительные знаки (??) в JavaScript?
Что такое двойные вопросительные знаки (??) в JavaScript?
Как безопасно обрабатывать неопределенные и нулевые значения в коде с помощью Nullish Coalescing
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание API-ресурса Laravel может быть непростой задачей. Она требует глубокого понимания возможностей Laravel и лучших практик, чтобы обеспечить...
Как сделать компонент справочного центра с помощью TailwindCSS
Как сделать компонент справочного центра с помощью TailwindCSS
Справочный центр - это веб-сайт, где клиенты могут найти ответы на свои вопросы и решения своих проблем. Созданный для решения многих распространенных...
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
3
1
69
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Я бы явно сопоставил не `.

s/`[^`]*`[^`]*`//

Regex жадный, `.+` соответствует чему угодно, от первой до последней обратной кавычки.

Я понимаю, что это тенденции, просто не был уверен, как обойти это.

timtimbruno 10.01.2023 22:45

В последнем поле ввода отсутствует обратная сторона конца.

Walter A 11.01.2023 11:57

С ГНУ awk:

awk 'BEGIN{FPAT = "GO:[0-9]+"; OFS = "\t"} {$1=$1; print}' file

Вывод разделен табуляцией:

GO:1234567  GO:5373845  GO:5438534

GO:3333333  GO:5553535

От man awk:

FPAT: регулярное выражение, описывающее содержимое полей в записи. Если установлено, gawk анализирует входящие помещать в поля, где поля соответствуют регулярному выражению, вместо использования значения FS в качестве разделитель полей.

См.: 8 мощных встроенных переменных Awk — FS, OFS, RS, ORS, NR, NF, FILENAME, FNR

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

timtimbruno 12.01.2023 20:43
Ответ принят как подходящий
sed -E 's/\t`[^\t]*//g'
  • \t- вкладка
  • ` - буквальная обратная галочка
  • [^\t]* - любой символ без табуляции 0 или более раз

Альтернатива:

sed -E 's/\t(`[^`]*){2}`?//g'
  • \t - вкладка
  • ( - старт группы
    • ` - буквальная обратная галочка
    • [^`]* - любые не обратные кавычки 0 и более раз
  • ) - конец группы
  • {2} - повторить группу дважды
  • `? - необязательная обратная кавычка (поскольку в последнем столбце только 2 вместо 3)

... и замените пустой строкой.

Выход:

GO:1234567      GO:5373845      GO:5438534
.
GO:3333333      GO:5553535
.
.

Примечание. В этих примерах предполагается, что между столбцами есть ровно один tab. Здесь трудно увидеть.

Спасибо. Это прекрасно работает. [^`] для меня новое.

timtimbruno 10.01.2023 22:44

Если в строке есть abc GO:3333333, то это не сработает.

anubhava 10.01.2023 23:02

@anubhava Ну, между этими столбцами нет замены, это правда. Возможно, мне не следовало позволять исходному выражению OP влиять на меня, а вместо этого читать инструкцию «Я хочу сохранить только определенную строку (GO:#######)». :-)

Ted Lyngmo 10.01.2023 23:16

Если вы хотите поддерживать поле обратной кавычки в начале строки и поле GO в конце (не требуется в текущем вопросе), вы можете использовать sed -r 's/(\t|^)[^\t]+(\t|$)/==\ т/г'`

Walter A 11.01.2023 11:50

Это awk решение будет работать с любой версией awk:

awk '
BEGIN {
   FS=OFS = "\t"
}
{
   for (i=1; i<=NF; ++i)
      if ($i ~ /^GO:/)
         s = (s ? s OFS : "") $i
   print s
   s = ""
}' file

GO:1234567  GO:5373845  GO:5438534
GO:3333333  GO:5553535
GO:3333333

Этот шаблон \t`.+`\t соответствует от табуляции, за которой следует `, до последнего вхождения того же шаблона, который совпадает слишком много.

Кажется, что в частях, начинающихся с обратной галочки, нет пробелов, которые вы хотите удалить.

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

Если вы удалите несколько последовательных полей или поле в начале или в конце, могут возникнуть пробелы с несколькими вкладками, которые вы также можете заменить пустой строкой.

sed -E 's/(\t|^)`[^[:space:]]*//g;s/^\t+|\t+$|//g;s/\t{2,}/\t/g' file

Содержимое файла с разделителями табуляции

GO:1234567  `text1`moretext`    GO:5373845  `diff`text` GO:5438534  `text`text
.
GO:3333333  `txt`text`  GO:5553535  `misc`text
..
`txt`text`  GO:3333333  `txt`text`  `txt`text`  `txt`text`  GO:5553535  `misc`text  `misc`text

Выход

GO:1234567      GO:5373845      GO:5438534
.
GO:3333333      GO:5553535
..
GO:3333333      GO:5553535

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

Использование вложенного цикла for Напишите сценарий bash для проверки соответствия символов и типа данных в любых двух записях поля.
Чтобы разделить и расположить число в одиночном инвертированном
Сценарий оболочки — свертывание чисел
Вывести все номера столбцов для определенного символа
Как использовать сценарий PowerShell для запуска интерфейса командной строки Terraform и передачи переменной типа map?
Ожидается операнд синтаксической ошибки (токен ошибки "-") в сценарии оболочки
Как удалить сообщения журнала в файле на основе метки времени / сообщения старше 7 дней должны быть удалены из файла
GOLANG: Почему SetDeadline/SetReadDeadline/SetWriteDeadline не работает с файлом при использовании os.File.Fd()?
Нужно ли использовать «1>» при перенаправлении стандартного вывода в терминале Linux?
Подсчитайте общее количество пользователей в Linux (системные пользователи не включены)