Удостоверьтесь, что существует символ в конце каждой строки

У меня есть файл со следующим содержанием.

This
is,
are,,,
a,,

Я хочу заменить конец строки с единственной запятой. Если нет никакой запятой в конце строки, затем добавляют одну запятую и если существует больше чем одна запятая, затем заменяют его единственной запятой.

вывод, похожи на это

This,
is,
are,
a,
5
задан 16 July 2016 в 04:50

2 ответа

В случае, если существуют возможные запятые, промежуточные

Медленнее затем sed опция на меньших файлах, но быстрее на больших файлах (протестированы на 10 МБ), опция Python ниже.

Также, если существует возможность из запятых в другом месте в строках, длинной - лайнер ниже будет работать:

python3 -c "ls = open('file').read().splitlines(); [print( (',').join([s for s in l.split(',') if not s == ''])+',') for l in ls]"

или немного короче:

python3 -c "[print( (',').join([s for s in l.split(',') if not s == ''])+',') for l in open('f').read().splitlines()]"

..., где 'file' полный путь в Ваш файл, между (единственный!) кавычки.

пример

на файле:

something like, for example this
here, read this line, I added some commas,,,,,,,,
are, you convinced or not,
just say something, anything

... вывод:

something like, for example this,
here, read this line, I added some commas,
are, you convinced or not,
just say something, anything,

Объяснение

ls = open('file').read().splitlines()

чтения файл, разделения это в строки

[s for s in l.split(',') if not s == '']

разделения строка разделителем , удаляет (возможную) запятую (запятые) из конца строки

(',').join([s for s in l.split(',') if not s == ''])+','

соединения разделы разделения, добавляет запятая в конце.

5
ответ дан 23 November 2019 в 08:38

Самый простой подход должен использовать sed с оперативным редактированием:

sed -i 's/,*$/,/' file

-i вносит изменения в тот же файл. Можно использовать i.bak создать a file.bak файл резервной копии оригинала. Можно также выполнить его без -i видеть изменения, прежде чем они будут применены. s/foo/bar/ оператор замены. Это заменит первую инстанцию foo с bar. $ отмечает конец строки, и * означает "0 или больше". Так, s/,*$/,/ означает "замену 0 или больше запятых в конце строки с одной запятой". Если никакие запятые не будут там, то каждый будет добавлен и если будет больше чем один, то они будут заменены единственным.

Некоторые другие опции, ради завершения:

  • Perl

    perl -i -pe  's/,*$/,/' file
    

    Та же идея как sed выше. Это то, где sed добрался -i идея от.

    Если скорость будет проблемой, то этот будет самым быстрым из всех решений здесь:

    perl -i -lne 'printf join ",", (grep {$_ ne ""}split(/,/) ); print ","' file
    
  • awk

    awk '{sub(/,*$/,",")}1;' file >newfile
    

    Или, с более новыми версиями (g) awk:

    awk -iinplace '{sub(/,*$/,",")}1;' file
    
  • Чистая оболочка (медленнее и менее эффективный, только включенный как пример):

    while read line; do echo "${line/%,*/},"; done < file > newfile
    

    ${var/%foo/bar} заменит любого foo от конца переменной var с bar. Здесь, мы заменяем все после последней запятой, таким образом, это не будет работать, если у Вас будет несколько запятых на строку, она только работает над Вашим примером. Другие решения не имеют ни одного из этих ограничений.

19
ответ дан 23 November 2019 в 08:38

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

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