Existem várias maneiras de fazer isso. Dependendo do seu tipo de ferramenta preferido, você pode escolher um sobre outro
AWK
A maneira mais apropriada. Definir palavras 1,2,3 para seqüência vazia e imprimir
$ wmctrl -l | awk '{$1=$2=$3="";print}'
Como alternativa para se livrar do espaço principal, você pode fazer isso:
$ wmctrl -l | awk '{for(i=4;i<=NF;i++) printf "%s ",$i;print ""}'
corte
Uma aproximação um pouco desajeitada, nós imprimimos tudo depois de um campo específico até o campo 9999. Por que 9999? -f
flag aparentemente precisa saber range, então com input que tem um número arbitrário de palavras por linha, nós obviamente não podemos saber o range, mas podemos usar algo suficientemente grande, daí 9999.
$ wmctrl -l | cut -d " " -f 5-9999
Perl
Podemos aproveitar o modo -a
autosplit, em que palavras de cada linha lidas de stdin são divididas em array. Isso potencialmente poderia ser melhorado e encurtado.
$ wmctrl -l | perl -lane 'my $numels=scalar @F;print @F[3..$numels]'
Python
Um pouco longo mas funciona. O Python não tem o modo de divisão automática como perl, mas podemos fazer isso manualmente em cada string.
$ wmctrl -l | python -c "import sys; print '\n'.join([' '.join(line.split()[3:]) for line in sys.stdin])"
Como alternativa, podemos usar um script curto para simular o cut
, em vez do one-liner. Isso funcionaria muito melhor para textos / entradas multilinhas e é muito mais legível
#!/usr/bin/env python
import sys
start=int(sys.argv[1])
for line in sys.stdin:
print " ".join(line.strip().split()[start:])
E chame da seguinte forma:
$ wmctrl -l | ./print_words.py 3
SED
Desta forma, aproveita as expressões regulares. Nós combinamos a string desde o começo da linha ^
até o limite da palavra parrot
com \b
e após o espaço, e os deletamos (efetivamente configurando a string nula)
$ wmctrl -l | sed 's/^.*\bparrot\ //'
Como alternativa, para evitar a correspondência gananciosa, podemos usar o seguinte:
$ wmctrl -l | sed 's/^[^ ]* *[^ ]* *[^ ]* //'
O padrão não é muito complexo. Iniciamos a correspondência no início da linha e combinamos qualquer número de caracteres (a *
part) que não são espaço ( [^ ]
part) três vezes separados por qualquer número de espaços. Portanto, ^[^ ]*
corresponde à primeira palavra, *
corresponde a qualquer número de espaços, segundo [^ ]*
corresponde à segunda palavra e segundo *
corresponde ao segundo espaço, finalmente com [^ ]*
correspondendo à terceira palavra mais espaço.
BASH + xargs
Podemos aproveitar a capacidade do bash para iterar sobre argumentos de linha de comando e passar cada linha (-L 1) como um conjunto de argumentos de linha de comando para bash -c ' '
. O resto é simples - obtemos os primeiros 3 argumentos e imprimimos o resto
wmctrl -l | xargs -L 1 bash -c 'for i in 1 2 3;do shift ; done ; printf "%s " "$@";printf "\n"' sh
Alternativamente, como sugerido por Stephane Chazelas nos comentários: enquanto houver pelo menos três argumentos posicionais sendo passados de wmctrl -l
(que neste caso deve ser consistentemente verdadeiro), a solução pode ser reduzida para:
wmctrl -l | xargs -L 1 bash -c 'shift 3;printf "%s " "$@";printf "\n"' sh