perl -lane '$,="\t";
$. == 1 and @A = grep $F[$_] =~ /VI/, 0..$#F;
print @F[0,@A];
' yourfile
ID OVI 1VI 3VI
er 23 23 23
tr 24 24 24
$. == 1
извлечь индексы полей, содержащих строку VI
. @A
, мы просто идем вперед и вырезаем 1-е поле + поля, перечисленные в массиве @A
, из Массив @F
. Для OFS=$,
установлено значение TAB
. YMMV. awk -v OFS="\t" '
NR==1{
for ( i=2; i<=NF; i++ )
if ( $i ~ /VI/ )
str = str OFS i
N = split(str, A, OFS)
}{
s = $1
for ( i=2; i<=N; i++ )
s = s OFS $(A[i])
$0 = s
}1
' yourfile
sed -e '
# TAB->spc, multiple spc -> single spc, trim leading/trailing spc
y/ / /;s/[ ]\{2,\}/ /g;s/^[ ][ ]*//;s/[ ][ ]*$//
# only for first line, remove the first field and store remaining in hold area
1{
h
s/[ ]/\
/
s/.*\n//
x
}
# append hold area (which now has 2nd...last fields
# data of the first record) to the present line and
# place a marker at the end of the first field
G
s/[^ ][^ ]*[ ]/&\
/
# setup a do-while loop which progressively either keeps VI data or trims it
:loop
# 1 2 3
s/\(\n\)\([^ ][^ ]*\)[ ]\{0,1\}\(.*\n\)[^ ]*VI[^ ]*[ ]\{0,1\}/ \2\1\3/;tloop
s/\(\n\)[^ ][^ ]*[ ]\{0,1\}\(.*\n\)[^ ][^ ]*[ ]\{0,1\}/\1\2/
/\n\n$/!bloop
# loop ends when the two \ns collide at the end of line
# remove the two \ns and what remains is what you wanted
s///
' yourfile
Вы можете привязать поиск к концу строки и подсчитать сколько угодно дополнительных символов:
grep 'X.$'
будет искать "X "в качестве предпоследнего символа,
grep 'X.\{4\}$'
будет искать" X "как пятый последний символ и т. д.
Я предлагаю использовать GNU grep:
echo abcdef | grep -Po '.(?=.{1}$)'
Вывод:
e
echo abcdef | grep -Po '.(?=.{3}$)'
Вывод:
c