Как мне найти второй последний или n-й последний символ в каждой строке файла

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

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

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
0
03.01.2017, 15:00
2 ответа

Вы можете привязать поиск к концу строки и подсчитать сколько угодно дополнительных символов:

grep 'X.$'

будет искать "X "в качестве предпоследнего символа,

grep 'X.\{4\}$'

будет искать" X "как пятый последний символ и т. д.

6
28.01.2020, 02:14

Я предлагаю использовать GNU grep:

echo abcdef | grep -Po '.(?=.{1}$)'

Вывод:

e

echo abcdef | grep -Po '.(?=.{3}$)'

Вывод:

c
2
28.01.2020, 02:14

Теги

Похожие вопросы