sed
не подходит для этого. Попробуйте awk
:
$ awk -v OFS='\t' 'NR==1{for (i=1;i<=NF;i++)if ($i=="ddd"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}' file
aaa bbb ccc eee fff
1 2 3 5 6
2 3 4 6 0
Предполагается, что удаляемая строка, ddd
в данном случае, отображается как поле в первой строке.
-v OFS = '\ t'
Устанавливает разделитель выходных полей на табуляцию. Если вы используете что-то еще, измените это.
NR == 1 {for (i = 1; i <= NF; i ++) if ($ i == "ddd") {n = i-1; m = NF- (i == NF)}}
Это просматривает все столбцы в первой строке. Мы сохраняем номер столбца с ddd
(минус один) в переменной n
.
Он также устанавливает m
равным номеру последнего столбца, за исключением случая, когда i
является последним столбцом, и в этом случае он устанавливает его в NF-1
.
for (i = 1; i <= NF; i + = 1 + (i == n)) printf "% s% s", $ i, i == m? ORS: OFS
Это распечатывает каждое поле, пропуская поле, в котором ddd
появилось в первой строке.
i + = 1
увеличит i
на единицу в каждом цикле. i + = 1 + (i == n)
увеличивает i
на единицу в каждом цикле, кроме случая i == n
, в этом случае i
увеличивается на 2. Это приводит к пропуску правого столбца.
printf "% s% s", $ i, i == m? ORS: OFS
печатает столбец i
, за которым следует либо разделитель столбцов, OFS
, либо разделитель строк, ORS
, в зависимости от того, является ли i
последним столбцом.
Для тех, кто предпочитает такие команды, записанные на нескольких строках:
awk -v OFS='\t' '
NR==1{
for (i=1;i<=NF;i++)
if ($i=="ddd") {
n=i-1
m=NF-(i==NF)
}
}
{
for(i=1;i<=NF;i+=1+(i==n))
printf "%s%s",$i,i==m?ORS:OFS
}
' file
Если мы хотим, чтобы ввод и вывод были разделены запятыми, нам нужно изменить оба разделитель полей ввода (с -F
) и разделитель полей вывода. Например, рассмотрим этот входной файл:
$ cat file2
aaa,bbb,ccc,ddd,eee,fff
1,2,3,4,5,6
2,3,4,5,6,0
Затем используйте:
$ awk -F, -v OFS=, 'NR==1{for (i=1;i<=NF;i++)if ($i=="ddd"){n=i-1;m=NF-(i==NF)}} {for(i=1;i<=NF;i+=1+(i==n))printf "%s%s",$i,i==m?ORS:OFS}' file2
aaa,bbb,ccc,eee,fff
1,2,3,5,6
2,3,4,6,0