В bash это можно сделать с помощью внутренних команд tail
иcut
:
#! /bin/bash
# Get header line
header=$( head -n 1 data_file )
# Make a variable with all delimiters (2)
delimiters=${header//[^;]/}
# Make an array with all column names
declare -a colnames=( ${header//;/ } )
# For all columns one at the time...
for C in $(seq 2 $((${#delimiters}+1)) ) ; do
index=$((C-1))
# Skip first 3 lines of data_file
tail --lines=+3 data_file | cut -d\; -f1,$C | while read; do
# Replace first ';' with column name
line=${REPLY/;/;${colnames[$index]};}
# Remove all spaces and print
echo ${line// /}
done
done
Пояснение:
Получить первую строку файла в переменную (, которую затем можно изменить)
header=$( head -n 1 data_file )
Удалить все символы из переменной, за исключением разделителя cemi -двоеточие
delimiters=${header//[^;]/}
Теперь переменная $delimiters содержит ';;'
Заменить все ';' с пробелами. Это даст «N A B». Один или несколько пробелов являются разделителями массива:
declare -a colnames=( ${header//;/ } )
Получить количество символов в переменной:
${#delimiters}
Добавить один:
$((${#delimiters}+1))
Тогда
$(seq 2 $((${#delimiters}+1)) )
равно:
$(seq 2 3 )
Индекс в переменной идет от 0..n, затем -1 для поиска имен столбцов:
index=$((C-1))
Прочитать файл, пропустить первые 3 строки, показать только номер столбца $C
,прочитать строку в переменную$REPLY
:
tail --lines=+3 data_file | cut -d\; -f1,$C | while read; do
Обычно каждая строка правильно сформированного CSV-файла имеет одинаковое количество столбцов, что может нарушить работу, но...
awk 'BEGIN{ FS=OFS="," }
$1 == "test_1" { print $1,$2,$4,$5; next } 1' yourfile
Сsed
:
sed '/^test_1/s/,[^,]*//2' file
/^test_1/
поиск строк, начинающихся с test_1
, затем s/,[^,]*//2
заменить второе вхождение запятой, за которой следуют любые символы, не являющиеся запятыми -, пустой строкой Выполняется командой ниже
awk -F "," '$1 == "test_1" {$3=""}1' filename|sed -r "s/\s+/,/g"
выход
test_1,2,hi,cat
test_2,3,4,5,6
test_1,3,8,9