Получение только имени приложения из wmctrl -l

Я пытаюсь просто получить имя приложения из этого кода:

wmctrl -l 

но я не знаю, как это сделать!

  • Можно ли изменить порядок глобуса?
  • найти все файлы cpp и перечислить только те файлы с именами, которые соответствуют шаблону (regex), не работают
  • Если я нахожу «sudo» в начале одного лайнера, применим ли он к остальным командам?
  • Стойкие аргументы оболочки
  • Добавить строку из файла в имя файла
  • Определить папку в bash
  • Если бы вы могли объяснить, как я мог это сделать, это было бы здорово.

    РЕДАКТИРОВАТЬ:

    Выходной сигнал wmctrl -l равен:

     0x01000007 -1 parrot Top Expanded Edge Panel 0x01000017 -1 parrot Bottom Expanded Edge Panel 0x01200006 -1 parrot x-caja-desktop 0x03600006 0 parrot Terminal 0x03000130 0 parrot scripting - Getting a string after a word in BASH - Unix & Linux Stack Exchange - Google Chrome 

    так что мне нужно все после parrot

  • Повторно запустить несколько команд истории
  • В чем разница между встроенной командой echo и / bin / echo?
  • Как выполнить команду Bash и выполнить два утверждения при сбое?
  • grep-файлы из списка
  • Можно ли эмулировать более старые версии Bash?
  • Где находятся детали «Расширение пути» и «Расширение брекета» на странице руководства?
  • 5 Solutions collect form web for “Получение только имени приложения из wmctrl -l”

    Есть несколько способов сделать это. В зависимости от вашего предпочтительного типа инструмента вы можете выбрать один из них

    AWK

    Наиболее подходящий способ. Установите слова 1,2,3 в пустую строку и распечатайте

     $ wmctrl -l | awk '{$1=$2=$3="";print}' 

    Альтернативно, чтобы избавиться от ведущего пространства, вы можете сделать это:

     $ wmctrl -l | awk '{for(i=4;i<=NF;i++) printf "%s ",$i;print ""}' 

    порез

    Немного неудобный подход, мы печатаем все после определенного поля до поля 9999. Почему 9999? Флаг -f видимому, должен знать диапазон, поэтому при вводе, который имеет произвольное количество слов в строке, мы, очевидно, не можем знать диапазон, но мы можем использовать что-то достаточно большое, следовательно, 9999.

     $ wmctrl -l | cut -d " " -f 5-9999 

    Perl

    Мы можем использовать режим автосплит, где слова каждой строки, считанные из stdin, разбиваются на массив. Это потенциально может быть улучшено и сокращено.

     $ wmctrl -l | perl -lane 'my $numels=scalar @F;print @F[3..$numels]' 

    питон

    Немного длинный, но работает. У Python нет автоматического режима разделения, например perl, но мы можем сделать это вручную для каждой прочитанной строки.

     $ wmctrl -l | python -c "import sys; print '\n'.join([' '.join(line.split()[3:]) for line in sys.stdin])" 

    В качестве альтернативы мы можем использовать короткий скрипт для имитации cut вместо однострочного. Это будет работать намного лучше для многострочных текстов / входов и более читаемо

     #!/usr/bin/env python import sys start=int(sys.argv[1]) for line in sys.stdin: print " ".join(line.strip().split()[start:]) 

    И назовите это так:

     $ wmctrl -l | ./print_words.py 3 

    SED

    Этот способ использует регулярные выражения. Мы сопоставляем строку с начала строки ^ до символа границы слова с \b и следующим пробелом и удаляем их (эффективно устанавливая нулевую строку)

     $ wmctrl -l | sed 's/^.*\bparrot\ //' 

    Альтернативно, чтобы избежать жадного соответствия, мы можем использовать следующее:

     $ wmctrl -l | sed 's/^[^ ]* *[^ ]* *[^ ]* //' 

    Шаблон не слишком сложный. Мы начинаем сопоставлять в начале строки и сопоставляем любое количество символов ( * часть), которые не являются пробелами ( [^ ] часть), три раза разделенные любым количеством пробелов. Итак, ^[^ ]* соответствует первому слову, * соответствует любому числу пробелов, второй [^ ]* соответствует второму слову, а второй * соответствует второму пробелу, наконец, с [^ ]* совпадением третьего слова плюс пробел.

    BASH + xargs

    Мы можем использовать способность bash перебирать аргументы командной строки и передавать каждую строку (-L 1) в виде набора аргументов командной строки для bash -c ' ' . Остальное просто – мы получаем rids из первых трех аргументов и печатаем остальное

     wmctrl -l | xargs -L 1 bash -c 'for i in 1 2 3;do shift ; done ; printf "%s " "$@";printf "\n"' sh 

    В качестве альтернативы, как было предложено Стефаном Чазеласом в комментариях: до тех пор, пока по крайней мере 3 позиционных аргумента передаются из wmctrl -l (который в этом случае должен быть последовательно истинным), решение можно сократить до:

     wmctrl -l | xargs -L 1 bash -c 'shift 3;printf "%s " "$@";printf "\n"' sh 

    Вы можете использовать cut, так как wmctrl (правильно) не имеет параметров фильтрации. Вероятно, это то, что вы хотите:

     wmctrl -l | cut -d ' ' -f 4- 
     sed -n 's/.* parrot //p' 

    Распечатал бы то, что справа от самого правого появления " parrot " на линиях, содержащих " parrot " . Это потому, что это .* Выше жадно и будет соответствовать как можно больше.

    В вашем случае это будет проблемой для вывода, например:

     0x03a00003 0 parrot parrot (~) (1 of 2) - GVIM 

    Если вы хотите напечатать то, что находится справа от самого левого появления " parrot " , общий трюк заключается в том, чтобы сделать:

     sed -n '/ parrot /{ s//\ /; s/.*/\n/p }' 

    То есть мы заменяем первое (настолько левое) появление " parrot " с новой строкой (символ, который иначе никогда не будет найден в пространстве шаблонов). И затем удалите все до этой новой строки (которая, как гарантируется, будет уникальной).

    Здесь, однако, похоже, что вы хотите получить название окон от клиента- parrot , поэтому из строк, где третье поле является parrot , так:

     sed -n 's/^[^ ]\{1,\} \{1,\}[^ ]\{1,\} \{1,\}parrot //p' 

    Или с perl :

     perl -ne 'print if s/^\H+\h+\H+\h+parrot //' 

    Обратите внимание, что мы предполагаем, что названия окон не содержат символов новой строки, которые обычно имеют место, но не гарантируются. Попробуйте, например, после:

     xterm -n $'foo\nbar' 

    Если вы хотите это объяснить, вы можете сделать это:

     perl -0777 -ne '$prefix = qr{0x[\da-f]+\h+-?\d+\h+}; print for /^${prefix}parrot (.*?\n)(?=$prefix|$)/gms' 

    Это означает, что все записи начинаются с 0x<hex> <dec> чтобы определить, где начинаются и заканчиваются записи. Это не было бы полностью безупречным (например, для случая, когда кто-то делает xterm -n $'foo\n0x0 0 parrot something' ), но должен быть в порядке, если не сталкиваться со злонамеренными пользователями.

    Вы можете использовать:

     wmctrl -l | sed 's/|/ /' | awk '{$1=$2=$3=""; print $0}' 

    который не будет считать «-» в «-1» для липких окон в виде столбца.

    Вы можете обрезать выход фиксированной ширины с помощью wmctrl -l | cut -c15- wmctrl -l | cut -c15-

    Linux и Unix - лучшая ОС в мире.