замена символов в 3-м столбце с помощью sed/awk

Файлы имеют 3 столбца:

123711184642,3583090366663629,0036f920012437d4 123715942138,3538710295145500,0136f920afd6c643

Я хочу удалить первые два символа в третьем столбце: 123711184642,3583090366663629,36f920012437d4 123715942138,3538710295145500,36f920afd6c643

И поменяйте местами первые 6 символов по два в третьем столбце так, чтобы окончательный результат был следующим:

Любая помощь будет оценена по достоинству. Берни


person bernie    schedule 05.01.2011    source источник
comment
Я спотыкаюсь или в примере данных только два столбца?   -  person JUST MY correct OPINION    schedule 05.01.2011
comment
Есть 3 столбца, разделенные запятой,.   -  person bernie    schedule 05.01.2011


Ответы (5)


Предполагая, что ваши входные данные находятся в файле «foo», вы можете сделать:

cat foo | awk -F "," -f awkfile

где awkfile будет содержать:

{
  v = ""
  p = $3
  printf ("%s,%s,", $1, $2)
  for (i=3; i<9; i=i+2) {
     printf ("%s%s", substr(p, i+1, 1), substr (p, i, 1))
  }
  printf ("%s\n", substr(p, 9))
}
person kvista    schedule 05.01.2011
comment
Привет, Келли. Что-то здесь не так: 0136f920afd6c643 имеет 16 цифр. После запуска сценария awk он становится 639f02fafd6c643. Это 15 цифр, а не 14 цифр. Также обратите внимание, что есть лишняя буква f. В оригинале всего две буквы f. - person bernie; 05.01.2011
comment
Извините, последний substr(p, 10) должен был быть substr(p, 9), а предыдущий цикл должен был быть исправлен на ‹ 9. Я отредактировал свой ответ и убедился, что он соответствует целевому результату, который вы опубликовали. Еще раз извините за это - я должен был перепроверить в первую очередь. - person kvista; 05.01.2011
comment
Нет необходимости использовать cat. - person Dennis Williamson; 06.01.2011

С sed это просто вопрос группировки:

sed '
    s/\(.*,\)../\1/;
    s/,\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\([^,]*\)$/,\2\1\4\3\6\5\7/' file
person marco    schedule 05.01.2011

С тарабарщиной:

gawk -F, '
    BEGIN {OFS=FS}
    { 
        $3 = gensub(/^..(.)(.)(.)(.)(.)(.)(.*)/, "\\2\\1\\4\\3\\6\\5\\7", 1, $3)
        print
    }
' in.txt
person glenn jackman    schedule 05.01.2011

sed 1-строчный. Неважно, сколько полей у вас есть, если вы просто хотите изменить последнее. Ему также все равно, сколько пар имеет последнее поле, он все равно поменяет их местами.

sed 'h;s/^.,..//;s/(.)(.)/\2\1/g;x;s/,[^,]$ /,/;G;s/\n//' /путь/к/файлу

Вход

$ cat ./infile
123711184642,3583090366663629,0036f920012437d4
123715942138,3538710295145500,0136f920afd6c643

Выход

$ sed 'h;s/^.*,..//;s/\(.\)\(.\)/\2\1/g;x;s/,[^,]*$/,/;G;s/\n//' ./infile
123711184642,3583090366663629,639f021042734d
123715942138,3538710295145500,639f02fa6d6c34

Объяснение

  1. h -- сделать копию всего
  2. s/^.*,..// -- Пространство шаблона теперь содержит только последнее поле с удаленными двумя ведущими числами.
  3. s/\(.\)\(.\)/\2\1/g -- Поменять местами числа парами в пространстве шаблонов
  4. x -- поменять местами пространство шаблона с пространством удержания
  5. s/,[^,]*$/,/ -- Удалить все последнее поле
  6. G -- Добавляем пространство хранения к пространству шаблона с помощью '\n' между ними
  7. s/\n// -- Удалите '\n', добавленный G
person SiegeX    schedule 05.01.2011
comment
Выходные данные не соответствуют запрошенным выходным данным. - person Dennis Williamson; 06.01.2011

awk Однострочник просто для удовольствия. Неважно, сколько пар чисел находится в 3-м поле, оно будет работать для всех из них.

awk -F, '{$3=substr(gensub(/(.)(.)/,"\2\1","g",$3),3)}1' OFS=, /path/to /файл

Вход

$ cat ./infile
123711184642,3583090366663629,0036f920012437d4
123715942138,3538710295145500,0136f920afd6c643

Выход

$ awk -F, '{$3=substr(gensub(/(.)(.)/,"\\2\\1","g",$3),3)}1' OFS=, ./infile
123711184642,3583090366663629,639f021042734d
123715942138,3538710295145500,639f02fa6d6c34
person SiegeX    schedule 05.01.2011
comment
Выходные данные не соответствуют запрошенным выходным данным. - person Dennis Williamson; 06.01.2011