Как удалить начальный символ из определенного столбца в файле с разделителями канала? - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть текстовый файл с разделителями в виде трубы, подобный этому

TEST|F123433|F123433|TEST
TEST|F123434|F123434|TEST
TEST|F123435|F123435|TEST
TEST|F123436|F123436|TEST
TEST|F123437|F123437|TEST

Я пытаюсь удалить начальный 'F' из столбцов 2 и 3. Вот ожидаемый результат.

TEST|123433|123433|TEST
TEST|123434|123434|TEST
TEST|123435|123435|TEST
TEST|123436|123436|TEST
TEST|123437|123437|TEST

Я попытался сделать это, используя sed, как показано ниже, но он удаляет «F» только из столбца 2, но не из столбца 3

sed 's/^TEST|F/TEST|/g'

Ответы [ 7 ]

0 голосов
/ 26 декабря 2018
awk '{gsub(/\|F/,"|")}1' file

TEST|123433|123433|TEST
TEST|123434|123434|TEST
TEST|123435|123435|TEST
TEST|123436|123436|TEST
TEST|123437|123437|TEST
0 голосов
/ 30 декабря 2018

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

$ cat > bala.txt
TEST|F123433|F123433|TEST
TEST|F123434|F123434|TEST
TEST|F123435|F123435|TEST
TEST|F123436|F123436|TEST
TEST|F123437|F123437|TEST

$ perl -F"[|]" -lane ' s/^.// for @F[1..2] ; print join("|",@F) ' bala.txt
TEST|123433|123433|TEST
TEST|123434|123434|TEST
TEST|123435|123435|TEST
TEST|123436|123436|TEST
TEST|123437|123437|TEST
0 голосов
/ 21 декабря 2018

Это может работать для вас (GNU sed):

sed -r 's/(F|([^F|]?))([^|]*)/\2\3/2;s/(F|([^F|]?))([^|]*)/\2\3/3' file

Удаляет первый символ F столбца, разделенного | для столбцов два и три.Он использует тот факт, что непревзойденная обратная ссылка пуста, и, таким образом, использование такой ссылки в RHS замены будет эффективно удалять предыдущее совпадение.

0 голосов
/ 21 декабря 2018

С sed, используя группы захвата:

sed -E -n 's/^(TEST\|)F(.*)F(.*)/\1\2\3/p'

Вывод:

TEST|123433|123433|TEST
TEST|123434|123434|TEST
TEST|123435|123435|TEST
TEST|123436|123436|TEST
TEST|123437|123437|TEST
0 голосов
/ 21 декабря 2018

Не могли бы вы попробовать просто awk тоже.Использование функции sub для 2-го и 3-го полей.

awk 'BEGIN{FS=OFS="|"} {sub(/^F/,"",$2);sub(/^F/,"",$3)} 1'  Input_file
TEST|123433|123433|TEST
TEST|123434|123434|TEST
TEST|123435|123435|TEST
TEST|123436|123436|TEST
TEST|123437|123437|TEST
0 голосов
/ 21 декабря 2018

С sed (и это относится только к указанному примеру), вы можете глобально заменить |F на |:

$ sed -E 's/\|F/\|/g' file

. Вы можете ограничить первые два экземпляра * 1007.* (не обязательно номера столбцов) с двумя неглобальными заменами с sed:

sed -e 's/\|F/\|/' -e 's/\|F/\|/' file

или в форме ERE:

$ sed -E 's/^([^|]*)\|F/\1|/; s/([^|]*)\|F/\1|/' file

Лучше и гибчеПолевое решение с awk позволяет указать, какой столбец:

$ awk  'BEGIN{FS=OFS="|"} {for (i=2; i<=3;i++)sub(/^F/,"",$i);}1' file
TEST|123433|123433|TEST
TEST|123434|123434|TEST
TEST|123435|123435|TEST
TEST|123436|123436|TEST
TEST|123437|123437|TEST
0 голосов
/ 21 декабря 2018

Вам нужно использовать группу захвата для копирования всего во 2-м столбце после F.

sed 's/^TEST|F\([^|]*\)|F/TEST|\1|/'

Нет необходимости использовать модификатор g, так как вы делаете только одну заменуна строку (и шаблон с привязкой ^ или $ может совпадать только один раз).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...