как объединить содержимое файла с увеличением последнего номера столбца

#bash #shell #awk #sed #echo

Вопрос:

у меня есть файл с некоторым содержимым, и мне нужно повторить n-й раз и добавить приращение номера последнего столбца.

 Input content of a file:
TCTA    7   ccta    TCTA    1
TCTA    8   ccta    TCTA    1
TCTA    9   ccta    TCTA    1
TCTA    10  ccta    TCTA    1
TCTA    11  ccta    TCTA    1
TCTA    12  ccta    TCTA    1
TCTA    13  ccta    TCTA    1
TCTA    14  ccta    TCTA    1
TCTA    15  ccta    TCTA    1
TCTA    16  ccta    TCTA    1
TCTA    17  ccta    TCTA    1

Expected output:
TCTA    7   ccta    TCTA    1
TCTA    8   ccta    TCTA    1
TCTA    9   ccta    TCTA    1
TCTA    10  ccta    TCTA    1
TCTA    11  ccta    TCTA    1
TCTA    12  ccta    TCTA    1
TCTA    13  ccta    TCTA    1
TCTA    14  ccta    TCTA    1
TCTA    15  ccta    TCTA    1
TCTA    16  ccta    TCTA    1
TCTA    17  ccta    TCTA    1
TCTA    7   ccta    TCTA    2
TCTA    8   ccta    TCTA    2
TCTA    9   ccta    TCTA    2
TCTA    10  ccta    TCTA    2
TCTA    11  ccta    TCTA    2
TCTA    12  ccta    TCTA    2
TCTA    13  ccta    TCTA    2
TCTA    14  ccta    TCTA    2
TCTA    15  ccta    TCTA    2
TCTA    16  ccta    TCTA    2
TCTA    17  ccta    TCTA    2
TCTA    7   ccta    TCTA    3
TCTA    8   ccta    TCTA    3
TCTA    9   ccta    TCTA    3
TCTA    10  ccta    TCTA    3
TCTA    11  ccta    TCTA    3
TCTA    12  ccta    TCTA    3
TCTA    13  ccta    TCTA    3
TCTA    14  ccta    TCTA    3
TCTA    15  ccta    TCTA    3
TCTA    16  ccta    TCTA    3
TCTA    17  ccta    TCTA    3
TCTA    7   ccta    TCTA    n
TCTA    8   ccta    TCTA    n
TCTA    9   ccta    TCTA    n
TCTA    10  ccta    TCTA    n
TCTA    11  ccta    TCTA    n
TCTA    12  ccta    TCTA    n
TCTA    13  ccta    TCTA    n
TCTA    14  ccta    TCTA    n
TCTA    15  ccta    TCTA    n
TCTA    16  ccta    TCTA    n
TCTA    17  ccta    TCTA    n
 

Я попытался следовать, но не смог увеличить последний столбец в n-й раз.

 for i in {1..5};do 
   cat file.txt >> out.txt
done
 

Мне нужно, чтобы последняя колонка увеличилась в n-й раз.

Комментарии:

1. Гарантируется ли, что входной файл будет иметь тот же номер в последнем столбце? Гарантировано ли, что это число будет единицей? Если число отличается, следует ли повторять строки только до тех пор, пока конечное число не будет увеличено до указанного максимального значения (т. Е. Должны ли некоторые строки появляться в выводе больше раз, чем другие)?

2. На каждой итерации вы должны заменить последнее число в строке текущим порядковым номером. Поэтому вы не можете использовать cat. Вместо этого вы должны — внутри каждой итерации i — писать явный цикл по строкам входного файла и для каждой строки корректировать последнее поле строки.

Ответ №1:

Использование решения gnu-awk:

 awk -v n=3 '
{
   rec = rec $0 RS
}
1
END {
   for (i=2; i<=n;   i)
      printf "%s", gensub(/[0-9] (n|$)/, i "\1", "g", rec)
}' file

TCTA    7   ccta    TCTA    1
TCTA    8   ccta    TCTA    1
TCTA    9   ccta    TCTA    1
TCTA    10  ccta    TCTA    1
TCTA    11  ccta    TCTA    1
TCTA    12  ccta    TCTA    1
TCTA    13  ccta    TCTA    1
TCTA    14  ccta    TCTA    1
TCTA    15  ccta    TCTA    1
TCTA    16  ccta    TCTA    1
TCTA    17  ccta    TCTA    1
TCTA    7   ccta    TCTA    2
TCTA    8   ccta    TCTA    2
TCTA    9   ccta    TCTA    2
TCTA    10  ccta    TCTA    2
TCTA    11  ccta    TCTA    2
TCTA    12  ccta    TCTA    2
TCTA    13  ccta    TCTA    2
TCTA    14  ccta    TCTA    2
TCTA    15  ccta    TCTA    2
TCTA    16  ccta    TCTA    2
TCTA    17  ccta    TCTA    2
TCTA    7   ccta    TCTA    3
TCTA    8   ccta    TCTA    3
TCTA    9   ccta    TCTA    3
TCTA    10  ccta    TCTA    3
TCTA    11  ccta    TCTA    3
TCTA    12  ccta    TCTA    3
TCTA    13  ccta    TCTA    3
TCTA    14  ccta    TCTA    3
TCTA    15  ccta    TCTA    3
TCTA    16  ccta    TCTA    3
TCTA    17  ccta    TCTA    3
 

Комментарии:

1. Привет, Анубхав, Спасибо, что он работает (мне нужно установить; «заварить, установить gawk» и использовал gawk вместо awk только). Более того, я никогда не использовал функцию gensub, не могли бы вы объяснить все, как ваши команды объясняют ситуацию ? Спасибо

2. gensub использует регулярное [0-9] (n|$) выражение для поиска в строке rec . Который в основном является последним числом в каждой строке и заменяет его тем, i которое повторяется от 2 до n . (n|$) это группа захвата для захвата каждого разрыва строки или конца строки, и вместо этого мы просто возвращаем ее обратно после i использования обратной ссылки \1 . "g" предназначен для глобальной замены.

3.Эй, Анубхав, Спасибо, вы можете мне помочь, если я хочу продлить для второго последнего столбца, а также для последнего столбца при изменении ввода? TCTA 3 TCTG 1 TCTA 1 TCTA 4 TCTG 1 TCTA 1

4. @SandeepKumar Очень трудно понять требование из раздела комментариев. Будет намного лучше, если вы создадите новый вопрос, и вы получите лучшую помощь.

Ответ №2:

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

 parallel -kq sed -E 's/S $/$((amp; {}))/;s/.*/echo "amp;"/e' file ::: {0..2}
 

Если вы хотите заменить последнее поле на приращение, используйте:

 parallel -kq sed -E 's/S $/{}/' file ::: {1..3}