Изменить найти и заменить каждую итерацию - PullRequest
0 голосов
/ 05 марта 2012

У меня следующая проблема.

У меня есть 3 каталога, в каждом из которых есть файл A.txt.

В пределах A.txt Я хотел бы заменить XXX значением. Однако это значение отличается для каждого каталога.

Вот простой пример использования sed.

cd 1

sed 's/XXX/123/g' A.txt > B.txt

cd ..

cd 2 

sed 's/XXX/456/g' A.txt > B.txt

cd ..

cd 2 

sed 's/XXX/789/g' A.txt > B.txt

cd ..

У меня есть около 10000 замен, поэтому это очень неэффективно.

К сожалению, значения замещения 123, 465 и т. Д. Не являются инкрементными, поэтому их придется читать из файла.

То есть in.txt содержит 123 456 789

Можно ли каким-либо образом создать цикл, который будет изменять значения, подлежащие замене на каждой итерации, путем ссылки на строки / столбцы файла или что-то еще?

Любой совет с благодарностью

DP

Я почти справился с этим.

for dir in 1 2 3

do

while read I

do

cd $dir

sed -n 's/XXX/'"$I"'/p' A.txt > B.txt

cd ..

done

done < in.txt

Но циклы неправильные, поэтому всегда получается конечное значение in.txt в B.txt

Есть предложения?

Спасибо

1 Ответ

1 голос
/ 05 марта 2012

sed принимает имя файла в качестве сценария:

sed -f sed.script

В некоторых версиях sed (особенно в (более старых?) HP-UX) есть ограничения на количество строк, которые могут появиться в сценарии sed - и ограничение там составляет около 100. Большинство версий sed не имеют явного ограничения, хотя ограничение может превышать 10000 замен.

Вы должны рассмотреть возможность создания набора сценариев, dir1.sed, dir2.sed и dir3.sed.

Затем вы можете написать:

for dir in 1 2 3
do
    (
    cd $dir &&
    sed -f ../dir$dir.sed A.txt > B.txt
    )
done

Обратите внимание, что если вам нужно сделать несколько проходов (потому что вам нужно было создать dir1.1.sed, dir1.2.sed, ... dir1.N.sed), то вам необходимо организовать редактирование B.txt на втором проходе и т. Д.

Обратите внимание на использование вложенной оболочки (...) для изоляции сценария управления от операций cd. Тогда нет нужды в cd ... Я косо смотрю на любой скрипт, который содержит ...; cd somedir; ...; cd ...

Некоторые версии sed (в соответствии с GNU) поддерживают модификацию файлов на месте: sed -i -f dir1.sed A.txt. В противном случае, если вам нужно сохранить A.txt, сначала сделайте копию, а затем отредактируйте копию:

for dir in 1 2 3
do
    (cd $dir; cp A.txt B.txt)
done

for dir in 1 2 3
do
    for script in 1 2 3 4 ... N
    do
        (
        cd $dir
        sed -f ../dir$dir.$script.sed B.txt > C.txt
        mv C.txt B.txt
        )
    done
done

Содержимое файлов сценария sed выглядит следующим образом:

s/XXX/123/
s/YYY/234/
s/zzz/abc/

и т. Д. - это sed команды.

...