Роздрукуйте стовпці у проході по імені заголовка


12

У мене є такий текстовий файл

foo bar baz
1   a   alpha
2   b   beta
3   c   gamma

Я можу використовувати awk для друку певних стовпців, наприклад 1 та 3, за допомогою {print $1, $3}, але я хочу вказати стовпці для друку, вказавши замість цього заголовка стовпця щось подібне {print $foo, $baz}. Це корисно, тому мені не потрібно відкривати файл і рахувати стовпці вручну, щоб побачити, який стовпець є, і мені не доведеться оновлювати скрипт, якщо номер стовпця чи порядок змінюються. Чи можу я це зробити за допомогою awk (або іншого інструмента оболонки)?

Відповіді:


17
awk '
NR==1 {
    for (i=1; i<=NF; i++) {
        f[$i] = i
    }
}
{ print $(f["foo"]), $(f["baz"]) }
' file
foo baz
1 alpha
2 beta
3 gamma

Це надзвичайно корисна ідіома. У мене дуже багато даних в електронних таблицях, і різні електронні таблиці можуть мати загальний підмножина стовпців, які мене цікавлять, але не обов'язково в тому ж порядку в усіх електронних таблицях або з однаковою кількістю інших стовпців до / між ними, щоб можна було експортувати їх у вигляді CSV або подібних, а потім просто запустити скрипт awk, використовуючи назви стовпців замість номерів стовпців, абсолютно неоціненний.


Це велика подяка та працює для моїх цілей. Чи можете ви уточнити, як це працює для будкого початківця? Що робить синтаксис f [$ i] в цьому, і як awk працює, які стовпці відповідають рядкам?
AlexLipp

Ласкаво просимо. Це абсолютно базовий синтаксис awk, просто шукайте поля та масиви на сторінці "awk man" (або в Google). Додайте print iта print $iі print f [$ i] `заяви у циклі тощо, щоб відстежити, що відбувається, якщо це допомагає.
Ед Мортон

1

Ви просите awk, але ви можете також використовувати більш спеціалізований інструмент для цього: csvtool.

csvtool -t ' ' -u ' ' namedcol foo,baz file

або

csvtool -t ' ' -u ' ' col 1,3 file

1

Якщо припустити, що файл - це файл TSV ("розділені вкладки значення"), використовуючи csvkit:

$ csvcut -t -c foo,baz file.tsv
foo,baz
1,alpha
2,beta
3,gamma

Вихід буде правильно відформатований CSV, але його можна буде легко змінити назад на TSV:

$ csvcut -t -c foo,baz file.tsv | csvformat -T
foo     baz
1       alpha
2       beta
3       gamma

-cВаріант csvcutможе також приймати номера і діапазони, а також може бути використаний для переставити стовпчики вхідних даних (особливість я часто НЕ хапаю в стандартних cutутилітах).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.