У меня есть файл, содержащий (много) строк, которые я хотел бы заменить, поэтому я подумал об использовании простой команды, например:
sed 's/string1/string2/g' file1 > out
Однако строк слишком много, чтобы повторять это вручную. Поэтому я составил список всех строк, которые нужно заменить, по одной строке, и назвал его файлом A. Затем я составил список всех строк замены и назвал его файлом B.
Есть ли способ сделать что-то вроде:
sed 's/line i of file A/line i of file B/g' file1 > out
для каждой строки файла А?
решение1
Было бы проще создать файл с входными и заменяющими строками на одной строке (предполагая, что ни входные, ни заменяющие строки не содержат пробелов). Тогда вы можете сделать что-то простое, например:
while read n k; do sed -i "s/$n/$k/g" file1; done < fileA
РЕДАКТИРОВАТЬ:
Увидев ответ Найкакина, я понял, что то же самое можно сделать с двумя файлами, объединив его предложение с моим:
paste fileA fileB | while read n k; do sed -i "s/$n/$k/g" file1; done
решение2
По сути, это ваша первая идея, но с командами подстановки, помещенными в файл, чтобы ими было легче управлять:
tmpfile=/tmp/Asasuser.$$ exec 3< файлA exec 4< fileB при чтении –r astring <&3 делать читать –r bstring <&4 echo "s/$astring/$bstring/" >> "$tmpfile" сделанный исполнитель 3<&- 4<&- sed –f "$tmpfile" файл1 > выход rm –f "$tmpfile"
Это предполагает, что fileA
и fileB
имеют одинаковое количество строк (и что это число больше нуля) и что ни в одной из них нет неэкранированных /
символов.
решение3
Мы можем просто сгенерировать команду, которая нам нужна. Допустим, файлы со списками называются lista и listb. Тогда мы можем использовать:
$ for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done
для генерации опции для sed. Теперь мы можем использовать его с eval. Допустим, наш файл называется test. Мы используем:
$ eval "sed" $(for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done) "test"
решение4
paste -d : fileA fileB | sed 's/\([^:]*\):\([^:]*\)/s%\1%\2%/' > sed.script
sed -f sed.script SOURCE-FILE
SOURCE-FILE
может быть как отдельным файлом, так и несколькими файлами. Текст в файлах fileA и fileB не может содержать двоеточия или символы процента, но может содержать пробелы.