отдельное значение в столбцах с условием в bash

#bash #awk #grep #conditional-statements

#bash #awk #grep #условные операторы

Вопрос:

Я получил текстовый файл, как показано ниже

 008 750 16.3763  1
028 572 -91.1915  2
031 421 -19.2564  1
113 265 -5.05956  1
147 099 38.017  1
154 161 -4.43984  1
170 101 28.2171  1
179 728 -31.2691  2
 

и я хотел бы отделить третий столбец на основе значения в четвертом столбце:
если четвертый столбец равен 1, то вставьте еще два столбца как «(значение третьего столбца) NA», если 2, сделайте его «NA (значение третьего столбца)», затем удалите третий и четвертый столбцы. Я получу

 008 750 16.3763    NA
028 572 NA        -91.1915  
031 421 -19.2564   NA
113 265 -5.05956   NA
147 099 38.017     NA
154 161 -4.43984   NA
170 101 28.2171    NA
179 728 NA        -31.2691 
 

Кто-нибудь может сказать мне, как добиться этого в команде bash?

Я подумал, что быстрый способ сделать это — заменить четвертый столбец на NA, если значение равно 1. если оно равно 2, переключите третий и четвертый столбцы, а затем замените 2 на NA.

 awk '{OFS="t";if($i==1) $i="NA"; print}' *.txt
 

Но я не знаю, как я могу переключать значения двух столбцов.

Спасибо! 🙂

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

1. Что вы пробовали до сих пор? Stackoverflow работает лучше всего, если вы показываете, что приложили усилия, показываете разработанный вами код (каким бы примитивным он ни был) и описываете проблемы, с которыми сталкивается код.

2. Я подумал, что быстрый способ сделать это — заменить четвертый столбец на NA, если значение равно 1. если оно равно 2, переключите третий и четвертый столбцы, а затем замените 2 на NA.

Ответ №1:

«замените четвертый столбец на NA, если значение равно 1. если оно равно 2, переключите третий и четвертый столбцы, а затем замените 2 на NA»

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

 $ awk '$4==1{$4="NA"} $4==2{$4=$3; $3="NA"} 1' OFS='t' 1.txt
008     750     16.3763 NA
028     572     NA      -91.1915
031     421     -19.2564        NA
113     265     -5.05956        NA
147     099     38.017  NA
154     161     -4.43984        NA
170     101     28.2171 NA
179     728     NA      -31.2691
 

Как это работает

  • $4==1{$4="NA"}

    Если четвертый столбец равен 1 , то мы устанавливаем его NA равным .

  • $4==2{$4=$3; $3="NA"}

    Если четвертый столбец равен 2 , то мы делаем четвертый столбец равным третьему столбцу , а затем заменяем третий столбец на NA .

  • 1

    Это загадочное сокращение awk от print-the-line. Если вам не нравится cryptic, вы могли бы использовать {print} вместо этого.

  • OFS='t'

    Это устанавливает разделитель полей при выводе на табуляцию.

Если разделителем полей при вводе является вкладка, то вы можете также указать это:

 awk -F't' '$4==1{$4="NA"} $4==2{$4=$3; $3="NA"} 1' OFS='t' 1.txt
 

Улучшено форматирование

В приведенном выше примере tab используется в качестве разделителя полей, а это означает, что столбцы не позволяют правильно выстраиваться в линию. Чтобы исправить это, мы можем использовать column -t :

 $ awk '$4==1{$4="NA"} $4==2{$4=$3; $3="NA"} 1' OFS='t' 1.txt | column -t
008  750  16.3763   NA
028  572  NA        -91.1915
031  421  -19.2564  NA
113  265  -5.05956  NA
147  099  38.017    NA
154  161  -4.43984  NA
170  101  28.2171   NA
179  728  NA        -31.2691
 

Ответ №2:

 $ awk '{ if ($4==1) {$4="NA"} else {$4=$3; $3="NA"} }1' file | column -t
008  750  16.3763   NA
028  572  NA        -91.1915
031  421  -19.2564  NA
113  265  -5.05956  NA
147  099  38.017    NA
154  161  -4.43984  NA
170  101  28.2171   NA
179  728  NA        -31.2691