Заменить «_» на «|» только в 5-м поле файла

Заменить «_» на «|» только в 5-м поле файла

Мой файл имеет следующее содержимое:

rat|minty|ruhul|balaji|rat_123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1_123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2_123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

Мне нужно заменить _на , |но только на 5-м поле.

Ожидаемый результат:

rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

решение1

С awk, используйтеgsub()на 5-м поле:

$ awk 'BEGIN{FS=OFS="|"} {gsub("_",FS,$5)}1' file
rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

Объяснение

  • BEGIN{FS=OFS="|"}
    Установите разделитель полей на |. Таким образом, мы можем обращаться $5как к 5-му полю и т. д.
  • {gsub("_",FS,$5)}
    Заменить все _в 5-м поле на FS. То есть на |.
  • 1
    Вызвать действие awk по умолчанию: распечатать текущую (измененную) запись.

решение2

При sedусловии, что 5-е поле имеет только один элемент _для замены

$ sed -E 's/^(([^|]+\|){4}[^_]+)_/\1|/' ip.txt 
rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

Решение с perl(аналогичным awkодному), если все _в 5-м поле необходимо заменить:

$ perl -F'\|' -lane '$F[4] =~ tr/_/|/; print join "|",@F' ip.txt 
rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

решение3

С perl:

$ perl -F'\|' -ne '$F[4]=~s/_/|/; print join "|", @F' file
rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

Makes -aдействует perlкак awk, разделяя каждую входную строку по символу, заданному , -Fна поля, сохраненные в массиве @F. Затем мы заменяем _на |5-е поле (массивы начинаются с 0, поэтому $F[4]5-е поле тоже), а затем печатаем массив, соединенный |.

Вы также можете установить разделитель массива на |и вывести "@F", что сделает то же самое, но более лаконично:

$ perl -F'\|' -ne '$"="|"; $F[4]=~s/_/|/; print "@F"' file
rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

Конечно, в вашем конкретном примере _пятое поле также является первым в строке, поэтому, если ваш файл действительно такой, то достаточно сделать:

$ perl -pe 's/_/|/' file 
rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

Или

$ sed 's/_/|/' file 
rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

Вы можете использовать тот же подход с awk:

$ awk -F'|' 'sub("_","|")' file 
rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

Или, чтобы указать только 5-е поле и заменить все вхождения _в 5-м поле, более короткая версия@fedorqui's ответ:

$ awk -F'|' -vOFS='|' 'gsub("_","|",$5)' file 
rat|minty|ruhul|balaji|rat|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat1|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat
rat|minty|ruhul|balaji|rat2|123|decode|rat_123|abc|def|ghi|jkl|rat|cde|ind|rat

Обратите внимание, что эти два awkрешения будут печатать только на строках, где подстановка прошла успешно. Если у вас могут быть строки, которые не соответствуют шаблону (нет _в 5-м поле), используйте вместо этого подход @fedorqui или один из подходов perl.

Связанный контент