Вставьте новые строки с отсутствующими значениями (NA)

Я хотел бы вставить новые строки в текстовые файлы, если отсутствуют значения. У меня есть, например, следующий текстовый файл (A.txt), для которого отсутствует строка 5. Кроме того, поскольку файл должен иметь 12 строк, строки 11-12 также отсутствуют.

1 2.30 2 3.01 3 3.22 4 3.34 6 3.01 7 2.90 8 2.99 9 3.00 10 3.02 

Мой ожидаемый результат следующий. Для отсутствующих случаев следует добавить строку с номером и NA. Как вы видите, это произошло по желанию в строках 5, 11 и 12:

 1 2.30 2 3.01 3 3.22 4 3.34 5 NA 6 3.01 7 2.90 8 2.99 9 3.00 10 3.02 11 NA 12 NA 

Я могу сделать это, используя следующий скрипт:

 f1=/my-directory/ echo "new file" > "$f1"/newfile.txt for i in {1..12}; do l=$(awk '{print $1}' /"$f1"/A.txt | grep -wE ^$i /"$f1"/A.txt) if grep --quiet -wE ^$i /"$f1"/A.txt; then echo "$l" >> "$f1"/newfile.txt; else echo "$i NA" >> "$f1"/newfile.txt; fi done 

Это прекрасно работает. Проблема в том, что мне нужно сделать это примерно для 600 файлов, содержащих более 160000 строк. Таким образом, решение цикла потребует слишком много времени для поиска по всем линиям. Мой вопрос: есть ли более простое решение, которое может это сделать?

  • Чтение заданных строк в файле - BASH
  • Разбор строк файла данных с помощью разделителя Вместо EOL
  • Как добавить верхний и нижний колонтитулы в плоский файл
  • Удалить строки, начинающиеся с #
  • Можно ли изменить файл yml с помощью сценария оболочки?
  • Конкретная замена уровня столбца
  • Отфильтруйте содержимое буфера обмена без использования промежуточного файла
  • Отфильтруйте пути из текстового файла, который глубже, чем их непосредственный предшественник
  • 5 Solutions collect form web for “Вставьте новые строки с отсутствующими значениями (NA)”

    Вы можете сделать это с помощью awk скрипта:

     awk '{ while (NR + shift < $1) { print (NR + shift) " NA"; shift++ }; print } END { shift++; while (NR + shift < 13) { print (NR + shift) " NA"; shift++ } }' /tmp/test1 

    будет выдавать требуемый результат для /tmp/test1 (замените это на каждый файл, который вы хотите обработать).

    В более читаемой форме:

     #!/usr/bin/awk -f { while (NR + shift < $1) { print (NR + shift) " NA" shift++ } print } END { shift++ while (NR + shift < 13) { print (NR + shift) " NA" shift++ } } 

    Сохраните это как файл, скажем, fill-missing , сделайте его исполняемым, тогда вы можете просто запустить

     ./fill-missing /tmp/test1 

    Скрипт обрабатывает каждую строку, отслеживая ожидаемую дельта с текущим номером строки в shift . Поэтому для каждой строки, если текущая строка не соответствует первому номеру в строке, она печатает соответствующий номер строки, а затем NA и увеличивает дельта; как только номера строк совпадают, он печатает текущую строку. В конце процесса он печатает любые недостающие строки, необходимые для достижения 12.

    здесь хорошо работает:

     join -a 1 -o 0,2.2 -e NA <(seq 12) A.txt 2>/dev/null 

    Я выбрасываю stderr, потому что join жалуется, если поле объединения не лексически отсортировано.

    файл awk

     BEGIN { i=1 ; } function upto(x) { while (i<x) printf "%d NA\n",i++ ;} { if ( $1 == i ) print ; upto($1) ; i++ ;} END { upto(final+1) ;} 

    называться

     awk -f nl.awk -v final=12 /tmp/test1 

    весь цикл

     cd /my/directory ls | while read f do awk -f ~/nl.awk -v final=12 $f > /an/other/dir/$f done 

    где

    • вы помещаете awk-программу в свой файл $ HOME ( ~/nl.awk )

    Вы также можете попробовать Python:

     #!/usr/bin/env python2 with open('file.txt') as f: check = 0 for line in f: if int(line.split()[0]) == check + 1: check = int(line.split()[0]) print line.rstrip() else: check = int(line.split()[0]) print int(line.split()[0]) - 1, 'NA' print line.rstrip() print int(line.split()[0]) + 1, 'NA' print int(line.split()[0]) + 2, 'NA' 

    Здесь мы сравниваем номер строки int(line.split()[0]) с check + 1 , мы установили начальное значение check как 0 . Если значения равны, мы напечатали линию, иначе мы напечатали желаемый контент, т. Е. Номер нужной строки и NA . Последние две строки используются для печати 11-й и 12-й строк.

    Glenn Jackman's bash и метод join с несколькими настройками, эта функция получает счет из входного файла и использует это значение как значение по умолчанию:

     # Usage: inlwmv file [ missing_value [ extra_lines ] ] # if unset, missing_value="NA", and extra_lines=0 inlwmv() { join -a 1 -o 0,2.2 -e "${2:-NA}" \ <(seq $((${3:-0} + $(tail -n 1 "$1" | cut -d ' ' -f1))) | sort -k 1b,1) \ <(sort -k 1b,1 "$1") | \ sort -g ; } 

    Для вопроса ОП:

     inlwmv A.file "" 2 

    Для этого дублированного вопроса версия Jackman терпит неудачу при последнем значении файла , ( join довольно тонкое в отношении порядка, но использование sort три раза заставляет его вести себя по мере необходимости):

     inlwmv afile 0 
    Interesting Posts

    компиляция оболочки nginx не выполняется

    Количество файлов не совпадает с inodes

    Как я могу получить DVD-диски в Debian?

    Могу ли я псевдоним `! <Editor>` в bashrc?

    Как извлечь первое имя в алфавитном порядке из нескольких файлов

    Как найти разницу между двумя метками времени до миллисекунды?

    VMware трассирует только хост-виртуальную машину через двойную виртуальную машину только для хоста / NAT

    независимо убедитесь, что TRIM действительно работает на SSD

    Почему моя попытка пересылки X11 завершилась с ошибкой «connect /tmp/.X11-unix/X0: нет такого файла или каталога»?

    Автономная установка драйверов wi-fi на старый ПК с использованием Linux Mint 15

    Есть ли какой-либо стандарт для разрешений для системных каталогов?

    Как написать / sys / со сценарием после перезагрузки? (Sudo)

    Переустановите поврежденный vmlinuz-linux

    Динамические переменные в файлах модулей systemd

    Обновление ядра на устройстве ARM

    Linux и Unix - лучшая ОС в мире.