Командний рядок: Витягнути підрядку з виводу


25

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

$ SayStuff

і вихід є

Watermelons and cucumbers

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

Будь-які ідеї?

Відповіді:


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

-d ' 'говоритьcut розділити на просторах. -f 3вибирає третю колонку.

Крім того, можна використовувати awk, що робить розщеплення , засноване на вже просторі і роблять стовпці доступні $1, $2...

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

Зверніть увагу, що при cutцьому не буде оброблено змінну кількість пробілів awk.
Zitrax

13

Можливо, я б скористався одним із варіантів, які вже надав @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

Якщо ви хочете ОСТАННЕ поле, ви, ймовірно, повинні використовувати awk .
У цьому випадку це стає:

$ echo "Кавуни та огірки" | awk '{print $ NF}'
огірки

У awkNF - кількість полів у рядку, тобто $NFозначає останнє поле у ​​рядку.


в основному те саме питання тут, але більш узагальнене: stackoverflow.com/questions/3162385/… Так, ви можете використовувати інші способи, але awk є найкоротшим
zeridon
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.