16

Скажи, я запускаю команду SayStuff

$ SayStuff

и вывод

Watermelons and cucumbers

Сейчас. Скажем, я хочу извлечь из строки cucumbers из подстроки и передать их во что-нибудь.
Путь к этому программно - разделить выходные данные в массив по разделителю Space и сослаться на него по ArrayName[2] . Я довольно новый для сценариев оболочки и только удался выкапывать пол загадочных примеров cut ни одно из которых имели смысл.

Есть идеи?

3 ответа3

26
$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3
cucumbers

-d ' ' указывает cut на пробелы. -f 3 выбирает третий столбец.

Вы также можете использовать awk , который выполняет разбиение по пространству и делает столбцы доступными как $1 , $2 ,…

$ echo "Watermelons and cucumbers" | awk '{ print $3 }'
cucumbers
12

Я бы, вероятно, использовал один из вариантов, уже предоставленных @slhck, но вот еще несколько способов сделать это:

  1. Используя массивы, как на любом другом языке:

    $ foo=( $(SayStuff) ) 
    $ echo ${foo[2]}
    cucumbers
    

    var=() объявляет массив, $(command) сохраняет выходные данные команды. Так, foo=( $(SayStuff) ) хранит выход SayStuff в foo массива , а затем yuou echo это третий элемент с ${foo[2]}

  2. sed

    $ SayStuff | sed 's/.* \(.*\)/\1/'
    cucumbers
    

    Команда sed заменит ( s/// ) все последним словом. Регулярное выражение сопоставляет все, что угодно, вплоть до пробела ( .* ), Которое будет соответствовать всему, вплоть до последнего пробела, а затем захватывает последнее слово (\(.*\) . Поскольку слово было зафиксировано, мы можем обозначить его как \1 .

    Более простая версия:

    $ SayStuff | sed 's/.* //'
    cucumbers
    
  3. удар

    $ foo=$(SayStuff); echo ${foo##* } 
    cucumbers
    

    При этом используются возможности манипуляции со строками в bash, подробности см. Здесь .

  4. Больше Баш

    $ SayStuff | while read a b c; do echo $c; done
    cucumbers
    
  5. Perl, где, конечно, есть много способов сделать это:

    $ SayStuff | perl -lane 'print $F[$#F]'
    cucumber
    

    Параметр -a заставляет perl вести себя как awk , разбивая строки в пробелах и сохраняя их в массив @F . Затем мы печатаем последний элемент @F ( $#F - количество элементов в @F ). -l указывает perl добавлять новую строку к каждому оператору print , -n что он должен построчно обрабатывать STDIN, и -e чтобы он запускал сценарий, указанный в командной строке.

    $ SayStuff | perl -pe 's/.* //'
    cucumber
    

    Опции были объяснены выше, мы просто удаляем все до последнего пробела и печатаем ( -p ).

    $ perl -le 'print $ARGV[$#ARGV]' $(SayStuff)
    cucumbers
    

    Здесь мы передаем Watermelons and cucumbers качестве аргументов, которые Perl сохранит в массиве @ARG и поэтому мы печатаем последний элемент @ARG .

  6. обман. Этот использует sed для преобразования пробелов в новые строки, а затем tail для печати только последней строки.

    $ SayStuff | sed 's/ /\n/g' | tail -n 1
    cucumbers
    
  7. grep и регулярные выражения, используя -o который печатает только совпадающую строку.

    $ SayStuff | grep -Po '\w+$' 
    cucumbers
    
  8. мошенничество

    $ SayStuff | grep -o cucumbers
    cucumbers
    
2

Вот еще несколько объяснений:

Usage: cut OPTION... [FILE]...

Print selected parts of lines from each FILE to standard output.

   -d, --delimiter=DELIM
          use DELIM instead of TAB for field delimiter

   -f, --fields=LIST
          select only these fields;  also print any line that contains  no
          delimiter character, unless the -s option is specified

Так что если вам нужно 3-е поле, и оно разделено пробелами '', то это

$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3  
cucumbers

Если вы хотите поле LAST, вы, вероятно, должны использовать awk.
В этом случае это становится:

$ echo "Арбузы и огурцы" | awk '{print $ NF}'
огурцы

В awk NF - количество полей в строке, поэтому $NF означает последнее поле в строке.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .