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

У меня есть двухколонный файл.txt, разделенный пробелами, но в первом столбце есть пробелы (которые являются ошибками). Мне нужно преобразовать его в CSV, но я не могу просто заменить все пробелы запятыми.

Пример ввода:

gi|118592783|ref|ZP_01550172.1|_biphenyl-2  3-diol_1    2-dioxygenase_[Stappia_aggregata_IAM_12614] 1

Желаемый вывод:

gi|118592783|ref|ZP_01550172.1|_biphenyl-23-diol_12-dioxygenase_[Stappia_aggregata_IAM_12614],1

Как я могу использовать sed (или что-то еще) заменить последний пробел в строке запятой, а затем удалить все оставшиеся пробелы? Будет ли это эффективно создать файл CSV?

4 ответа

Решение

Что-то вроде:

sed -r 's/(.*) /\1,/; s/ //g'

Первая замена, будучи жадной, покроет все, кроме последнего пробела в группе, заменив последнюю на ,, Второй затем устранит все остальное.

Perl

$ perl -ne 's/\s//g;s/^(.*)([[:digit:]])$/\1,\2/;print' input.txt                                                                                    
gi|118592783|ref|ZP_01550172.1|_biphenyl-23-diol_12-dioxygenase_[Stappia_aggregata_IAM_12614],1

или короче:

perl -pe 's/\s//g;s/^(.*)([[:digit:]])$/\1,\2/' input.txt 

По сути, это противоположность подхода Муру: сначала мы избавляемся от всех пробелов, а затем группируем все до последнего элемента (группа \1) и последний пункт (группа \2, два, что оказывается цифрой). Заменяем строку группой \1 а также \2 разделяя запятой.

Обратите внимание, что ([[:digit:]]) может быть изменен на (.) для ссылки на любой символ, если это необходимо (то есть, если мы ожидаем, что последний символ будет любого типа), или мы можем использовать ([[:graph:]]) иметь дело только с печатными символами

Вот гиковский путь - с помощью sed-петли.

  1. если шаблон содержит только один пробел, замените его запятой
  2. (иначе) заменить первый пробел ни на что и перейти к 1

который мы можем написать в GNU sed как

sed -e :1 -e '/^[^ ]* [^ ]*$/ s/ /,/' -e 's/ //; t1'

Тестирование:

$ echo 'gi|118592783|ref|ZP_01550172.1|_biphenyl-2  3-diol_1    2-dioxygenase_[Stappia_aggregata_IAM_12614] 1' | 
  sed -e :1 -e '/^[^ ]* [^ ]*$/ s/ /,/' -e 's/ //; t1'
gi|118592783|ref|ZP_01550172.1|_biphenyl-23-diol_12-dioxygenase_[Stappia_aggregata_IAM_12614],1

Это сделало бы работу:

sed -r "s/\s([0-9]+$)/,\1/" filename.txt | tr -d ' '

или же:

sed -r "s/\s([0-9]+$)/,\1/; s/\s//g" filename.txt

Пример ввода:

gi|118592783|ref|ZP_01550172.1|_biphenyl-2 3-diol_1    2-dioxygenase_[Stappia_aggregata_IAM_12614] 1

Выход:

gi|118592783|ref|ZP_01550172.1|_biphenyl-23-diol_12-dioxygenase_[Stappia_aggregata_IAM_12614],1
Другие вопросы по тегам