이 코드에서 애플리케이션 이름을 얻으려고 합니다.
wmctrl -l
하지만 어떻게 해야할지 모르겠어요!
이 작업을 수행하는 방법을 설명해 주시면 좋을 것 같습니다.
편집하다:
출력은 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
답변1
이를 수행하는 방법에는 여러 가지가 있습니다. 선호하는 도구 유형에 따라 도구를 선택할 수 있습니다.
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
진주
-a
자동 분할 모드를 사용하여 표준 입력에서 읽은 각 줄의 단어를 배열로 분할 할 수 있습니다 . 이는 개선되고 단축될 수 있습니다.
$ 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
이 접근 방식은 정규식을 사용합니다. ^
줄의 시작 부분부터 단어 경계 parrot
및 \b
다음 공백까지 문자열을 일치시킨 다음 제거합니다(효과적으로 빈 문자열로 설정됨) .
$ wmctrl -l | sed 's/^.*\bparrot\ //'
또한 탐욕스러운 일치를 피하기 위해 다음 방법을 사용할 수 있습니다.
$ wmctrl -l | sed 's/^[^ ]* *[^ ]* *[^ ]* //'
패턴은 그리 복잡하지 않습니다. 줄의 시작 부분부터 시작하여 *
공백이 아닌 문자(parts [^ ]
)를 원하는 수만큼 공백으로 구분하여 세 번 일치시킵니다. 따라서 ^[^ ]*
첫 번째 단어와 일치하고 *
공백 수와 일치하며 두 번째 단어 [^ ]*
는 두 번째 단어와 일치하고 두 번째는 *
두 번째 공백과 일치하며 마지막으로 [^ ]*
세 번째 단어와 공백이 일치합니다.
BASH + xargs
명령줄 인수를 반복하고 각 줄( -L 1 )을 명령줄 인수 집합으로 전달하는 bash의 기능을 활용할 수 있습니다 bash -c ' '
. 나머지는 간단합니다. 처음 3개의 인수를 제거하고 나머지를 인쇄합니다.
wmctrl -l | xargs -L 1 bash -c 'for i in 1 2 3;do shift ; done ; printf "%s " "$@";printf "\n"' sh
또는 Stephane Chazelas가 의견에서 제안한 것처럼 최소 3개의 위치 인수가 전달되는 한 wmctrl -l
(이 경우 항상 true여야 함) 솔루션을 다음과 같이 단축할 수 있습니다.
wmctrl -l | xargs -L 1 bash -c 'shift 3;printf "%s " "$@";printf "\n"' sh
답변2
답변3
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'
) 완전히 안전한 것은 아니지만 악의적인 사용자를 만나지 않을 때는 괜찮을 것입니다.
답변4
고정 너비 출력을 잘라낼 수 있습니다.
wmctrl -l | cut -c15-