echo '<e1 name="file1" id="id1" anotherId="id2">' |
sed -n 's/.*name="\([^"]*\)".*//p'
Ou com o GNU grep
se construído com suporte a PCRE:
echo '<e1 name="file1" id="id1" anotherId="id2">' |
grep -Po 'name="\K[^"]*'
Entrada:
<e1 name="file1" id="id1" anotherId="id2">
Saída desejada:
file1
Eu posso conseguir o que preciso com isso:
echo '<e1 name="file1" id="id1" anotherId="id2">' | sed 's/\(.*name="\)\(.*\)\(".*\)//' | sed 's/".*//'
Saída: file1
Gostaria de melhorar o conjunto de comandos e remover o último canal para sed, se possível. Se eu remover o último canal para sed, não consigo o que quero:
echo '<e1 name="file1" id="id1" anotherId="id2">' | sed 's/\(.*name="\)\(.*\)\(".*\)//'
Saída:
file1" id="id1" anotherId="id2
Como você pode ver, o sed está captando a última aspa e não o primeiro após o arquivo1.
Alguém pode ajudar a melhorar este comando?
Você pode simplificá-lo um pouco com esta versão:
$ echo '<e1 name="file1" id="id1" anotherId="id2">' | \
sed 's/.*name="\(.*\)" id.*//'
Você não precisa envolver tudo com parênteses, apenas as coisas que você está interessado em salvar para uso posterior, para que você possa removê-lo.
Você também pode usar a capacidade de grep
de usar o mecanismo de expressões regulares (PCRE) do Perl:
$ echo '<e1 name="file1" id="id1" anotherId="id2">' | \
grep -Po '(?<=name=")(\w+)(?=")'
A capacidade deste PCRE de olhar para frente e olhar para trás. A notação procura uma sequência de caracteres como "name="
antes do que estamos procurando. Este bit está fazendo isso:
(?<=name=")
Em seguida, ele procura uma série de caracteres de palavras. É o que estamos procurando:
(\w+)
A última parte que está fazendo a antecipação é esta:
(?=")
Está procurando por uma aspa ( "
) após o que estamos procurando.
$ echo '<e1 name="file1" id="id1" anotherId="id2">' | \
awk '{gsub("\"","");split($2,a,"="); print a[2]}'
Esta variante atribui as aspas duplas ('' '') fazendo uma substituição global:
gsub("\"","")
A string restante seria esta:
<e1 name=file1 id=id1 anotherId=id2>
Assim, podemos deixar awk
dividir isso normalmente e a segunda coluna seria o que estamos interessados em obter. Isso seria $2
to awk
. Então poderíamos pegar essa variável e então dividir em sinais de igual ( =
).
split($2,a,"=");
Isso dividirá $2
e armazenará os resultados em uma matriz, a
. Posteriormente, podemos imprimir o segundo elemento na matriz, sendo tudo do lado direito do sinal de igual de $2
.
file1