Как я могу изменить символ строки один за другим?

Вы можете использовать Vim в режиме Ex:

ex -sc '%s/\vPA|QU/RO/g|x' file
  1. % выберите все строки

  2. s замените

  3. \ v включить магию

  4. g глобальная замена

  5. x сохранить и закрыть

0
25.04.2019, 18:01
5 ответов

Использование sed:

Чтобы изменить два символа один за другим в строке,

sed -i 's/A/Y/;s/B/V/' file 

Для изменения и сохранения в разных файлах:

sed 's/A/Y/' file > file1; sed 's/B/V/' file > file1
0
28.01.2020, 02:18

Учитывая 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
4
28.01.2020, 02:18

Мы сделаем это, заставив 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.

0
28.01.2020, 02:18

Сделано описанным ниже методом, все работает нормально

    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
0
28.01.2020, 02:18

Я создал скрипт на основе пользовательского ввода, чтобы избежать ошибок

    #!/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
0
28.01.2020, 02:18

Теги

Похожие вопросы