Используйте 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
который мы можем написать в 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