Как вырезать (выделить) поле из текстовой строки, считая с конца?

32

Я знаю, как выбрать поле из строки, используя команду вырезать. Например, с учетом следующих данных:

a,b,c,d,e
f,g,h,i,j
k,l,m,n,o

Эта команда:

cut -d, -f2 # returns the second field of the input line

Возвращает:

b
g
l

Мой вопрос: как выбрать второе поле отсчета с конца? В предыдущем примере результат будет:

d
i
n
ПЛА
источник

Ответы:

52

Обратный ввод до и после cutс rev:

<infile rev | cut -d, -f2 | rev

Выход:

d
i
n
Тор
источник
1
У меня в папке с мусором много маленьких фрагментов. rcut предназначен именно для этого: #! / bin / bash rev | вырезать "$ @" | Преподобный
Джон
2
Жаль, что cutнельзя принимать отрицательные индексы полей (как, например, Python).
Кит Девенс
10

Попробуйте сделать это с помощью :

awk -F, '{print $(NF-1)}' file.txt

Или используя :

perl -F, -lane 'print $F[-2]' file.txt

Или используя (спасибо manatwork):

ruby -F, -lane 'print $F[-2]' file.txt

Или используя bash(спасибо manatwork):

while IFS=, read -ra d; do echo "${d[-2]}"; done < file.txt

Или используя :

cat file.txt |
python -c $'import sys\nfor line in sys.stdin:\tprint(line.split(",")[-2])'
Жиль Квено
источник
1
bashне нуждается в неподвижном количестве столбцов для этого: while IFS=, read -ra d; do echo "${d[-2]}"; done < file.txt.
manatwork
1
Кстати, ваше третье решение также работает, если вы измените perlс ruby.
manatwork
Спасибо, rubyдобавил, bashотредактировал.
Жиль Квено
1
Если 4-е поле может начинаться с -или (в зависимости от среды, оболочки или способа компиляции оболочки), может содержать символы обратной косой черты, то echoэто не вариант. Зачем вам нужно мошенник catEnate file.txtс ничего перед подачей его python!?. Тебе нужно read -Aа не read -aв ksh93а zsh. Отрицательные подписки работают в zshно только в последних версиях ksh93и bash. В более старых версиях вы можете использовать${d: -2:1}
Стефан Шазелас
2
@StephaneChazelas, я думаю, что вы имеете ${d[@]: -2:1}в виду в своем последнем предложении.
manatwork
0

Используя sed:

sed -E 's/^([^,]*,)*([^,]*)(,[^,]*){1}$/\2/' infile

Выход:

d
i
n

объяснение

  • ([^,]*,)* соответствует любому количеству символов без запятой, за которыми следует запятая, т. е. любое количество столбцов.
  • ([^,]*) соответствует столбцу.
  • (,[^,]*){1}соответствует одному столбцу в конце, если вы измените квантификатор {1}на {2}него, соответствует второму столбцу с конца и т. д.
Тор
источник