У меня есть файл со следующим содержанием.
This
is,
are,,,
a,,
Я хочу заменить конец строки с единственной запятой. Если нет никакой запятой в конце строки, затем добавляют одну запятую и если существует больше чем одна запятая, затем заменяют его единственной запятой.
вывод, похожи на это
This,
is,
are,
a,
Медленнее затем 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 == ''])+','
соединения разделы разделения, добавляет запятая в конце.
Самый простой подход должен использовать 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
. Здесь, мы заменяем все после последней запятой, таким образом, это не будет работать, если у Вас будет несколько запятых на строку, она только работает над Вашим примером. Другие решения не имеют ни одного из этих ограничений.