Eu preciso escrever um script de shell que encontre e imprima todos os arquivos em um diretório que comece com a string: #include
. Agora, eu sei como verificar se uma string está no arquivo, usando:
for f in `ls`; do
if grep -q 'MyString' $f; then:
#DO SOMETHING
fi
mas como posso aplicar isso à primeira linha? Eu pensei em talvez criar uma variável da primeira linha e verificar se ela começa com #include
, mas não tenho certeza de como fazer isso. Eu tentei o read
comando, mas não consigo ler uma variável.
Eu gostaria de ouvir outras abordagens para este problema; talvez oq? De qualquer forma, lembre-se, preciso verificar se a primeira linha começa com #include
, não se contém essa string. É por isso que encontrei essas perguntas: Como imprimir o conteúdo do arquivo somente se a primeira linha corresponder a um determinado padrão?
https://stackoverflow.com/questions/5536018/how-to-print-matched-regex-pattern-using-awk
eles não estão ajudando completamente.
É fácil verificar se a primeira linha começa com
#include
in (GNU e AT&T) sed:Ou simplificado (e compatível com POSIX):
Isso terá uma saída somente se o arquivo contiver
#include
na primeira linha. Isso só precisa ler a primeira linha para fazer a verificação, então será muito rápido.Então, um loop de shell para todos os arquivos (com sed) deve ser assim:
Se houver apenas arquivos (não diretórios) no arquivo pwd.
Se o que você precisa é imprimir todas as linhas do arquivo, uma solução semelhante ao primeiro código postado funcionará (versão GNU & AT&T):
Ou, (versão POSIXfied compatível com BSD):
Ou:
Para imprimir o conteúdo do arquivo em vez de seu nome, substitua o
printf
comando porcat < "$file"
.Se você
awk
suporta anextfile
extensão e não se importa com os possíveis efeitos colaterais da abertura de arquivos não regulares:Acima, estamos adicionando um
./
prefixo que estamos removendo posteriormenteFILENAME
para evitar problemas com nomes de arquivos contendo=
caracteres (ou um arquivo chamado-
) .Com
zsh
, você pode substituir./*
por./*(-.)
apenas passar arquivos regulares (ou links simbólicos para arquivos regulares como na[ -f ... ]
abordagem acima) paraawk
.Ou para imprimir o conteúdo do arquivo em vez do nome:
(esse é portátil).
Cuidado com o fato de que, com a
-q
opção habilitada,grep
sairá com status zero mesmo que ocorra um erro.Esta questão é um exemplo perfeito onde as soluções bash e sed são bastante complexas, mas a tarefa pode ser muito mais simples com (GNU) awk: