Слияние двух столбцов текстового файла в Linux

у меня есть текстовый файл с несколькими столбцами текста и значений. Эта структура:

CAR       38
     DOG  42
CAT       89
CAR       23
     APE  18

Если столбец 1 имеет строку, столбец 2 не имеет (или это на самом деле пустая строка). И наоборот: если столбец 1 пуст, столбец 2 имеет строку. Другими словами, "объект"(автомобиль, кошка, собака и т. д.) происходит в любом столбце 1 и столбце 2, но не оба.

Я ищу эффективный способ консолидации столбцов 1 и 2, чтобы файл выглядел так вместо этого:

CAR  38
DOG  42
CAT  89
CAR  23
APE  18

Я могу сделать это в скрипте Bash, используя while и if, но я уверен, что есть более простой способ сделать это. Кто-нибудь может помочь?

Ура! Z

2 ответов


попробуйте это:

column -t file

выход:

CAR  38
DOG  42
CAT  89
CAR  23
APE  18

Обратите Внимание: Если:

  • вы ищете выход с авто-размер, левая выровненная фиксированная ширина столбцы (самое длинное значение поля определяет ширину, а более короткие значения заполняются пробелами справа)
  • и довольны два пробела в качестве разделителя столбцов
  • и файлы достаточно маленькие, чтобы читать в память в целом,

использовать Сайрус проще, column-на основании ответа.

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


awk ваш друг здесь:

awk -v OFS='  ' '{ print ,  }' file
  • awk по умолчанию разбивает строки на поля пробелами, поэтому при вводе строки, такие как CAR 38 и DOG 42 анализируются одинаково (CAR и DOG стать полем 1, , и 38 и 42 стать полем 2, ).
  • -v OFS=' ' устанавливает разделитель выходного поля в два пробела (по умолчанию - одно пробел); обратите внимание, что не будет обивка выходных значений для создания соответствие выход.

создать соответствие вывод с полями различной ширины, используйте Awk's printf функция, которая дает вам больше контроля над выходом; например следующие выходы 10-char-wide левый выровненный 1-й столбец и 2-char-широкий правый выровненный 2-й столбец:

awk '{ printf "%-10s  %2s\n", ,  }' file
  • обратите внимание, что ширина столбцов должна быть известна заранее.
  • напротив, column -t удобно определяет ширину столбца автоматически, сначала анализируя все данные, но это имеет последствия для производительности и потребления ресурсов; см. ниже.

сравнение производительности / потребления ресурсов между column -t и Awk подход:

  • column -t необходимо проанализировать все входные данные спереди, в первом проходе, чтобы иметь возможность определить максимум ширина входного столбца; из того, что я могу сказать, он делает это, читая вход в целом сначала в память, что может быть проблематично с большими входными файлами.
  • напротив, решение Awk считывает строки один за другим, но полагается на знание ширины столбца впереди время.

таким образом,

  • column -t будет потребляйте память пропорционально размеру входного сигнала, а awk использовать постоянный объем памяти.
  • column -t и как правило, медленнее, в зависимости от используемой реализации Awk;mawk гораздо быстрее, gawk немного быстрее, BSD awk медленнее(!); результаты, основанные на 10-миллионном файле ввода строки; команды, выполняемые на OSX 10.10.2 и Ubuntu 14.04.