LINUX.ORG.RU

Однократная замена в sed?

 


1

1

Есть скрипт вида

seps='\$\$'
let i=0
while [ "$i" -lt "$maxi" ]; do
        line="${array[$i]}"
        sed -i "s/$seps/$line/" "$file"
        #echo "[$i]: Заменяю [$seps] на [$line]..."
        let i=$i+1
done

Скрипт берет строчки из файла-2 и единожды заменяет определенную последовательность символов (в данном случае $$) из файла-1 на соответствующую строчку из файла-2 (номер строчки посли замены увеличивается на 1). Тесты показали, что все в порядке (в том числе прогон с echo), однако в реальной практике sed зачем-то заменяет $$ два раза, даже если явно указать s///1. Т.е. если должно быть $$ => a[0], $$ => a[1], $$ => a[2] и т.д., получаем примерно так: $$ => a[0], $$ => a[0], $$ => a[1], $$ => a[0], $$ => a[1], $$ => a[2]. Почему так?

Прошу прощения, если неясно сформулировал проблему.

Полный скрипт здесь: http://pastebin.com/drDSmyPm

Deleted

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

Поставил -r, от этого ничего не изменилось.

Deleted
()
Ответ на: комментарий от hope13

Чтобы было понятнее, прикладываю следующие файлы:

http://pastebin.com/X9tvxNQv - текст, в котором надо последовательно заменить $$ на строки отсюда: http://pastebin.com/EquXyDvN. Получиться должно следующее: http://pastebin.com/ezQQ6Ky1. А вместо этого получается следующее: http://pastebin.com/dfC0bVNc

Deleted
()
Ответ на: комментарий от derlafff

Должно заменяться только первое совпадение $$ на соответствующую фразу, не более. См. примеры с pastebin.

Deleted
()
$ cat file1
Lorem ipsum dolor sit $$, consectetur adipiscing elit. Duis ut neque est. Nam quis fringilla est. Fusce vulputate, eros non sodales laoreet, nunc sapien aliquet sem, $$ lacinia magna metus eu est. Pellentesque commodo consequat dolor. Integer sit amet leo et felis blandit condimentum $$ tempor ante. Vivamus sodales vehicula.

$ cat file2
amet
vitae
venenatis

$ cat test.sh
#!/bin/bash

let maxi=0
let i=0
while read line; do
	echo $line
        array[$i]="$line"
        let i=$i+1
done < "file2"

maxi=${#array}

seps='\$\$'
let i=0
while [ "$i" -lt "$maxi" ]; do
        line="${array[$i]}"
        echo "[$i]: Заменяю [$seps] на [$line]..."
        sed -e "s/$seps/$line/" -i '' file1
        let i=$i+1
done

$ ./test.sh
amet
vitae
venenatis
[0]: Заменяю [\$\$] на [amet]...
[1]: Заменяю [\$\$] на [vitae]...
[2]: Заменяю [\$\$] на [venenatis]...
[3]: Заменяю [\$\$] на []...

$ cat file1
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ut neque est. Nam quis fringilla est. Fusce vulputate, eros non sodales laoreet, nunc sapien aliquet sem, vitae lacinia magna metus eu est. Pellentesque commodo consequat dolor. Integer sit amet leo et felis blandit condimentum venenatis tempor ante. Vivamus sodales vehicula.
marvin_yorke ★★★
()
Последнее исправление: marvin_yorke (всего исправлений: 2)
Ответ на: комментарий от hope13

Странно, а в чем тогда разница между s///1 и, например, s///2, если sed все равно может заменить более одного совпадения за один проход при s///1?

Deleted
()
Ответ на: комментарий от derlafff

Sed работает сразу со всеми строками файла, а не до какого-то вхождения

Бугога!!!111

man sed

anonymous
()
Ответ на: комментарий от Deleted
0,/$seps/

Это адрес. от 0 до первого вхождения (включительно). Следующая команда будет применена только к этому диапазону.

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

Видимо зависит от реализации sed и наличия ошибок в конкретной версии.

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

Здесь имеется в виду одно совпадение в строке. У тебя так и было: в последней строке он менял только первое совпадение. Из-за этого такой странный сдвиг получился.

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