У меня есть большой файл с разделителями табуляции, в котором я хотел бы сохранить только определенную строку (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
.
.
Я бы явно сопоставил не `.
s/`[^`]*`[^`]*`//
Regex жадный, `.+` соответствует чему угодно, от первой до последней обратной кавычки.
Я понимаю, что это тенденции, просто не был уверен, как обойти это.
В последнем поле ввода отсутствует обратная сторона конца.
С ГНУ 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
Это удаляет точки из пустых строк, когда я их использую, в остальном это прекрасно работает.
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. Здесь трудно увидеть.
Спасибо. Это прекрасно работает. [^`] для меня новое.
Если в строке есть abc GO:3333333, то это не сработает.
@anubhava Ну, между этими столбцами нет замены, это правда. Возможно, мне не следовало позволять исходному выражению OP влиять на меня, а вместо этого читать инструкцию «Я хочу сохранить только определенную строку (GO:#######)». :-)
Если вы хотите поддерживать поле обратной кавычки в начале строки и поле GO в конце (не требуется в текущем вопросе), вы можете использовать sed -r 's/(\t|^)[^\t]+(\t|$)/==\ т/г'`
Это 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
Это очень странно, вывод вашего кода должен был быть GO:1234567 GO:5438534 text. Я не могу воспроизвести ваш вывод.