Вы можете использовать Vim в режиме Ex:
ex -sc '%s/\vPA|QU/RO/g|x' file
%
выберите все строки
s
замените
\ v
включить магию
g
глобальная замена
x
сохранить и закрыть
Использование sed:
Чтобы изменить два символа один за другим в строке,
sed -i 's/A/Y/;s/B/V/' file
Для изменения и сохранения в разных файлах:
sed 's/A/Y/' file > file1; sed 's/B/V/' file > file1
Учитывая sub.txt
подобное:
$ cat sub.txt
A -> Y
B -> V
C -> Q
D -> K
E -> L
F -> O
G -> P
H -> W
I -> X
J -> Z
Вы можете перебирать его в цикле оболочки, читая каждый из трех элементов в каждой строке в переменную:
while IFS=' ' read -r from ignore to; do... ; done < sub.txt
В этом цикле while
$from
будет исходным символом, а $to
будет символом, которым вы хотите его заменить. $ignore
посередине — это просто держатель для ->
.
Предполагается, что пробел и перевод строки(' '
и\n
)отсутствуют в списке символов, которые вы хотите транслитерировать.
Имея это в виду, вы можете использовать tr
, чтобы внести изменения и перенаправить вывод в новый файл:
while IFS=' ' read -r from discard to; do
printf '%s\n' "$string" | tr "$from" "$to" > changed."$from".txt
done < sub.txt
Обратите внимание, что некоторые реализации tr
завершатся ошибкой, если $from
или $to
равно [
или если они представляют собой многобайтовые -символы. Вышеприведенное также предполагает, что $from
не является /
.
Если string="ABCDEFGHIJ"
, приведенная выше команда создаст эти файлы:
$ ls changed*
changed.A.txt changed.D.txt changed.G.txt changed.J.txt
changed.B.txt changed.E.txt changed.H.txt
changed.C.txt changed.F.txt changed.I.txt
Со следующим содержанием:
$ for f in changed.*; do printf '%s\n' "=== $f ==="; cat "$f"; done
=== changed.A.txt ===
YBCDEFGHIJ
=== changed.B.txt ===
AVCDEFGHIJ
=== changed.C.txt ===
ABQDEFGHIJ
=== changed.D.txt ===
ABCKEFGHIJ
=== changed.E.txt ===
ABCDLFGHIJ
=== changed.F.txt ===
ABCDEOGHIJ
=== changed.G.txt ===
ABCDEFPHIJ
=== changed.H.txt ===
ABCDEFGWIJ
=== changed.I.txt ===
ABCDEFGHXJ
=== changed.J.txt ===
ABCDEFGHIZ
Это меняет каждый символ отдельно. Если вместо этого вы хотите сделать это постепенно, так что в 1-м файле будет изменен только 1-й символ, а во втором файле будут изменены как 1-й, так и 2-й символы, вы можете сделать:
tmpFile=$(mktemp)
printf '%s\n' "$string" > "$tmpFile"
while IFS=' ' read -r from ignore to; do
tr "$from" "$to" < "$tmpFile" > changed."$from".txt
cp changed."$from".txt "$tmpFile"
done < sub.txt
Это создаст следующие файлы:
$ for f in changed.*; do printf '%s\n' "=== $f ==="; cat "$f"; done
=== changed.A.txt ===
YBCDEFGHIJ
=== changed.B.txt ===
YVCDEFGHIJ
=== changed.C.txt ===
YVQDEFGHIJ
=== changed.D.txt ===
YVQKEFGHIJ
=== changed.E.txt ===
YVQKLFGHIJ
=== changed.F.txt ===
YVQKLOGHIJ
=== changed.G.txt ===
YVQKLOPHIJ
=== changed.H.txt ===
YVQKLOPWIJ
=== changed.I.txt ===
YVQKLOPWXJ
=== changed.J.txt ===
YVQKLOPWXZ
Мы сделаем это, заставив sed
работать с файлом sub.txt, чтобы сгенерировать sed
код, который будет работать с входными данными для получения различных выходных файлов, как показано здесь:
$ sed -ne '
1i\
h
s|\(.\)[[:blank:]*->[[:blank:]]*\(.\)|g;s/\1/\2/gw./converted.\1_\2.txt|p
'./sub.txt | sed -nf -./input.file
Получаем выходные файлы с именами converted.A_Y.txt
, converted.B_V.txt
и т. д. Первый вызов sed
генерирует код sed
на лету на основе преобразований, упомянутых во входных данных sub.txt, и использует его для запуска второго вызова sed
на входных данных.
Предположим, что в файле sub.txt используется односимвольная транслитерация и символы не являются регулярными выражениями для sed ни в правой, ни в левой части команды s///
команды sed
.
Сделано описанным ниже методом, все работает нормально
awk '{gsub("A","Y",$0);print $0}' l.txt > f_1.txt
awk '{gsub("B","V",$0);print $0}' l.txt > f_2.txt
awk '{gsub("C","Q",$0);print $0}' l.txt > f_3.txt
Я создал скрипт на основе пользовательского ввода, чтобы избежать ошибок
#!/bin/bash
echo "enter the character need to display"
read old
echo "enter the need character to be replaced"
read new
sed "s/$old/$new/g" r.txt>file_$old.txt
First it will ask for old content which need to be replaced.
Second it will ask for new content which needs to be replaced with old content
THird it saves the file after each iteration
Based on how characters need to be replaced you can add above mentioned script in for loop