Как извлечь конкретный столбец или строку из вывода команды?

Пример:

abcd@abcd-abcde:~$ xinput --list --short

Virtual core pointer

↳ SynPS/2 Synaptics TouchPad                id=11   [slave  pointer  (2)]

↳ Logitech USB RECEIVER                     id=12   [slave  pointer  (2)]

Как мне извлечь столбец из вывода, скажем, второй? И, например, сохранить его в переменной?

Можно ли это сделать?

2
задан 6 May 2016 в 14:03

3 ответа

Это точно, для чего awk был сделан. Используя вывод xinput в моей системе:

$ xinput --list --short
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ SIGMACHIP USB Keyboard                    id=12   [slave  pointer  (2)]
⎜   ↳ Logitech M325                             id=14   [slave  pointer  (2)]
⎜   ↳ AlpsPS/2 ALPS DualPoint Stick             id=17   [slave  pointer  (2)]
⎜   ↳ AlpsPS/2 ALPS DualPoint TouchPad          id=16   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Power Button                              id=8    [slave  keyboard (3)]
    ↳ SIGMACHIP USB Keyboard                    id=11   [slave  keyboard (3)]
    ↳ Dell WMI hotkeys                          id=18   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=13   [slave  keyboard (3)]
    ↳ Sleep Button                              id=9    [slave  keyboard (3)]
    ↳ UVC Camera (046d:0819)                    id=10   [slave  keyboard (3)]

$ xinput --list --short | awk -F"\t" '{print $2}'
id=2
id=4
id=12
id=14
id=17
id=16
id=3
id=5
id=6
id=7
id=8
id=11
id=18
id=13
id=9
id=10

awk автоматически разделит каждую входную строку на поля на значении, данном -F. По умолчанию это разделяет на пробеле, но здесь нам нужна вкладка. 1-е поле $1, второе $2 и т.д.

, С другой стороны, можно использовать cut:

$ xinput --list --short | cut -f2
id=2
id=4
id=12
id=14
id=17
id=16
id=3
id=5
id=6
id=7
id=8
id=11
id=18
id=13
id=9
id=10

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

$ ids=$(xinput --list --short | awk -F"\t" '{print $2}')
$ echo $ids
id=2 id=4 id=12 id=14 id=17 id=16 id=3 id=5 id=6 id=7 id=8 id=11 id=18 id=13 id=9 id=10
$ echo "$ids"
id=2
id=4
id=12
id=14
id=17
id=16
id=3
id=5
id=6
id=7
id=8
id=11
id=18
id=13
id=9
id=10

Вы могли также сохранить его как массив:

$ ids=( $(xinput --list --short | awk -F"\t" '{print $2}') )
$ echo ${ids[@]}
id=2 id=4 id=12 id=14 id=17 id=16 id=3 id=5 id=6 id=7 id=8 id=11 id=18 id=13 id=9 id=10
$ echo ${ids[2]}
id=12
10
ответ дан 7 May 2016 в 00:03

для извлечения столбца, Вы могли попробовать awk

% xinput --list --short | awk '{print $3}'
core
Virtual
SynPS/2
core
core
Button
Bus
...

для присвоения того вывода переменной a. обратите внимание, что значение этой переменной будет строкой, содержащей новые строки после каждого слова - не самое легкое для работы с. Вероятно, лучше присваивать массиву.

% a=$(xinput --list --short | awk '{print $3}')
vel@ubuntu:/media/michael/3ae9487f-1652-400e-8136-fe63519941ed% echo $a
core
Virtual
SynPS/2
core
core
Button
Bus
Button
USB2.0
WMI
Translated
1
ответ дан 7 May 2016 в 00:03
  • 1
    Проблема решена. Я следовал за превосходным ссылка , Вы дали. Я уменьшу системный раздел далее после того, как я удалю старую домашнюю папку. Экономя на внешних медиа, я понял, что rsync и mv могут быть сделаны на ~, но CP не так легко. / Только вопросом о руководстве является " при выполнении этого от LiveCd..., можно найти differences". я просто ожидал реверс, но я не эксперт. / Сохраняющий все персональные данные по отдельному разделу также звучит интересным. Я могу найти информацию о за и против этого, где-нибудь? Спасибо. – ycc_swe 19 October 2017 в 17:18

Зная, что объекты являются разделенной вкладкой, мы можем использовать путь только для оболочки с $IFS переменная и while read ; do . . .done структура.

$ xinput | while IFS= 

Для хранения объектов в переменной мы можем использовать массивы, и

$ xinput | { while IFS= 

Замечают меня использующий command | { command1 ; command2 ; command3 } структура. Вы быстро узнаете, что каналы запускают подоболочки, и переменные в подоболочках не влияют на основную оболочку , таким образом необходимо придумать некоторый способ сохранить те переменные.

Что касается извлечения строки, хорошо это довольно легко с grep:

    $ xinput | grep 'Virtual core keyboard'
    ⎣ Virtual core keyboard                     id=3    [master keyboard (2)] # extract line with specific string

    ↳ Toshiba input device                      id=12   [slave  keyboard (3)]
$ xinput | sed -n '3p' # extract 3rd line                                                          
⎜   ↳ SynPS/2 Synaptics TouchPad                id=11   [slave  pointer  (2)]
\t' read ONE TWO THRE ; do > array+=( "$TWO" ) > done ; > echo ${array[@]} > } id=2 id=4 id=11 id=3 id=5 id=6 id=7 id=8 id=9 id=10 id=12

Замечают меня использующий command | { command1 ; command2 ; command3 } структура. Вы быстро узнаете, что каналы запускают подоболочки, и переменные в подоболочках не влияют на основную оболочку , таким образом необходимо придумать некоторый способ сохранить те переменные.

Что касается извлечения строки, хорошо это довольно легко с grep:

    $ xinput | grep 'Virtual core keyboard'
    ⎣ Virtual core keyboard                     id=3    [master keyboard (2)] # extract line with specific string

    ↳ Toshiba input device                      id=12   [slave  keyboard (3)]
$ xinput | sed -n '3p' # extract 3rd line                                                          
⎜   ↳ SynPS/2 Synaptics TouchPad                id=11   [slave  pointer  (2)]
\t' read ONE TWO THRE ; do > echo $TWO > done id=2 id=4 id=11 id=3 id=5 id=6 id=7 id=8 id=9 id=10 id=12

Для хранения объектов в переменной мы можем использовать массивы, и

$ xinput | { while IFS= 

Замечают меня использующий command | { command1 ; command2 ; command3 } структура. Вы быстро узнаете, что каналы запускают подоболочки, и переменные в подоболочках не влияют на основную оболочку , таким образом необходимо придумать некоторый способ сохранить те переменные.

Что касается извлечения строки, хорошо это довольно легко с grep:

    $ xinput | grep 'Virtual core keyboard'
    ⎣ Virtual core keyboard                     id=3    [master keyboard (2)] # extract line with specific string

    ↳ Toshiba input device                      id=12   [slave  keyboard (3)]
$ xinput | sed -n '3p' # extract 3rd line                                                          
⎜   ↳ SynPS/2 Synaptics TouchPad                id=11   [slave  pointer  (2)]
\t' read ONE TWO THRE ; do > array+=( "$TWO" ) > done ; > echo ${array[@]} > } id=2 id=4 id=11 id=3 id=5 id=6 id=7 id=8 id=9 id=10 id=12

Замечают меня использующий command | { command1 ; command2 ; command3 } структура. Вы быстро узнаете, что каналы запускают подоболочки, и переменные в подоболочках не влияют на основную оболочку , таким образом необходимо придумать некоторый способ сохранить те переменные.

Что касается извлечения строки, хорошо это довольно легко с grep:

    $ xinput | grep 'Virtual core keyboard'
    ⎣ Virtual core keyboard                     id=3    [master keyboard (2)] # extract line with specific string

    ↳ Toshiba input device                      id=12   [slave  keyboard (3)]
$ xinput | sed -n '3p' # extract 3rd line                                                          
⎜   ↳ SynPS/2 Synaptics TouchPad                id=11   [slave  pointer  (2)]
2
ответ дан 7 May 2016 в 00:03
  • 1
    Решением 3 является в значительной степени самый безопасный и самый легкий способ сделать это. – Michael 19 October 2017 в 13:55

Другие вопросы по тегам:

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