LINUX.ORG.RU

продублировать строку


1

3

есть файл текстовый, такой формат

a

b

c

d

нужно дубль через запятую сделать без пробела.

a,a

b,b

c,c

d,d

можно както по проще?

спасибо

Перемещено hibou из talks

★★

Последнее исправление: qsloqs (всего исправлений: 1)

Ответ на: комментарий от chg

Тогда так: perl -pe 'chomp;$_.=",$_\n"'
Строковые операции быстрее, чем регулярки:

$ perl '-MBenchmark «cmpthese»' -e 'cmpthese(1000000,{regexp=>sub{$_=«text\n»;s/.*/$&,$&/},string=>sub{$_=«text\n»;chomp;$_.=",$_\n"}})'
Rate regexp string
regexp 88339/s  — -82%
string 502513/s 469% --

AITap ★★★★★
()
Ответ на: комментарий от AITap

да. выбрал самый короткий вариант :)

и оба варианта обламаются на вендофайлах под линуксом, оставив лишний символ \r в конце. в окончательном виде нужно добавить что-то вроде:

$/ = $^O eq 'MSWin32' ? «\r\n» : «\n»

нет, не так... предлагаю дописать это собравшимся самостоятельно :)

chg ★★★★★
()
Последнее исправление: chg (всего исправлений: 1)
Ответ на: комментарий от chg

Можно ещё поиграть с :crlf i/o layer, чтобы Perl сам всё транслировал, а $/ и $\ можно было бы назначить описанный в perlport «логический \n».

AITap ★★★★★
()
Ответ на: комментарий от cdshines

А какая разница? Я увидел скрипт на 4 строчки, поэтому и написал. Не вижу принципиальной разницы)

нафиг тут руби не нужен. Впрочем, дело ваше.

drBatty ★★
()
Ответ на: комментарий от anonymous

Еще немного укоротил. perl -ple 's/(.*)/$1$1\n/' fileName
Perl-golf'a тред.

перл как всегда сосёт у sed ;)

drBatty ★★
()
Ответ на: комментарий от chg

нет, не так... предлагаю дописать это собравшимся самостоятельно :)

s/\r$//

для sed

С другой стороны это в условие не входит, ибо изначальный sed скрипт отлично работает и с \r (правда выглядит это в Linux криво. Впрочем, это проблемы вендаюзеров).

drBatty ★★
()
Ответ на: комментарий от drBatty

Так я и не предлагаю его использовать. Я же говорю - увидел, что постят не только однострочники, и выебнулся. Правда, не с первого раза получилось)

cdshines ★★★★★
()
Ответ на: комментарий от drBatty

не совсем. записывается не намного длиннее, а работает побыстрее, потому что регулярное выражение значительно проще.

если здесь столько предложений, почему бы не рассмотреть и моё. (:

anarquista ★★★★★
()
Ответ на: комментарий от anarquista

не совсем. записывается не намного длиннее, а работает побыстрее, потому что регулярное выражение значительно проще.

регулярные выражения /.*/ и /\n/ работают с абсолютно одинаковой скоростью. Подробнее см. мою книжку. Или прямо исходники glibc. Каждое из этих выражений полностью пробегает всю строчку, при этом запоминаются позиции начала и конца совпадения.

если здесь столько предложений, почему бы не рассмотреть и моё. (:

твоё предложение довольно ценно, потому-что в более сложных случаях именно так и приходится действовать (когда критерий совпадения более сложный). А в этом случае долбить hold space не имеет особого смысла (впрочем, это достаточно дёшево).

drBatty ★★
()
Ответ на: комментарий от anarquista

В твоём случае пробегается вся строчка, в моём, вполне возможно, ровно половина. Разве нет?

нет. В glibc нет такой оптимизации. При любом раскладе, RE сначала компилируется, а потом применяется ко ВСЕЙ строке. Даже если это RE всего из одного символа. man 3 regexec для более полного понимания. Во всяком случае, я про такое не слышал. Дело в том, что средняя длинна строк обычно настолько малая, что нет смысла смотреть половину - строка всё равно обычно целиком влезет в одну линейку кеша L1.

drBatty ★★
()
Ответ на: комментарий от anarquista

и да, обычно ищется ПОСЛЕДНЕЕ совпадение, а для его поиска, очевидно, нужно просмотреть ВСЮ строчку. sed (точнее glibc) захватывает МАКСИМАЛЬНОЕ количество символов, ибо жадность выражений не регулируется, они всегда жадные. И это хорошо, ибо хотя надо просмотреть всю строчку, но это нужно только 1 раз. В отличие от нежадных выражений например из perl'а.

drBatty ★★
()
Ответ на: комментарий от anonymous

Есть же модификаторы, управляющие жадностью, поправьте если не прав.

в glibc нету. Есть в perl, ВНЕЗАПНО есть и в sed, если последнюю собирать в экспериментальном варианте (у меня, кстати, не получилось).

drBatty ★★
()
Ответ на: комментарий от drBatty

Но вот мой вариант не зависит от локали, и в юникодной, и в POSIX работает одинаково быстро.

а твой вариант заметно подтормаживает в юникодной и в полтора раза проигрывает моему по скорости в POSIX.

Объяснишь, почему?

anarquista ★★★★★
()
Ответ на: комментарий от xtraeft

памяти если не хватит на `cat text.txt` то да. Вроде ещё было ограничение на длину командной строки, не знаю, будет ли оно на builtin for действовать.

gorilych ★★
()
Ответ на: комментарий от gorilych

Не, на for это ограничение не действует. Но вот таким кодом можно запросто забить память с помощью bash:

for i in {-1000000..100000000}; do :; done
Проверено, убивает память не хуже знаменитого :(){ :|: & };: . Дядюшка OOM Killer его пришить может спокойно, но пока его позовут, нужно еще заполнить память и своп :3

nexfwall ★★★★
()
Ответ на: комментарий от anarquista

а твой вариант заметно подтормаживает в юникодной и в полтора раза проигрывает моему по скорости в POSIX. Объяснишь, почему?

точка совпадает с любым символом. Но символ, это не обязательно байт. Это может быть последовательность от одного, до пяти байтов. Потому, что-бы проверить, совпадает-ли текущий символ с точкой, надо для начала извлечь сам символ. В среднем, в русском тексте, один символ занимает примерно 1.5 байт (т.к. пробелы и спец-символы занимают по одному байту), потому и скорость примерно в 1.5 раза меньше. Странно, что твой вариант работает быстрее, очевидно, в последние годы, в glibc добавили оптимизацию выражений, которые можно проверить без посимвольного разбора. Это возможно потому, что символ \n встречается _только_ в самом \n, а в _любом_ символе utf-8 такого байта нет. Несколько лет назад выражение /\n/ работало точно также медленно, как и /.*/.

drBatty ★★
()
Ответ на: комментарий от gorilych

памяти если не хватит на `cat text.txt` то да. Вроде ещё было ограничение на длину командной строки

в Slackware 10.2 у меня неправильно работала строка

tar -cf archive.tar file1 file2 file3 ... file100500

ИЧСХ, никаких сообщений об ошибке, просто в архив добавились _не все_ файлы. Однако в современной системе повторить такое не получилось.

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.