Estou tendo problemas para usar o grep, os resultados retornados são "n-vazios", quero dizer, sem o caractere 'n'...
Este é o exemplo de script:
OLDIFS=$IFS
IFS="\\n"
i=$(grep -ril $1 *)
echo $i
IFS=$OLDIFS
Eu tentei com IFS='\n'
e IFS="\n"
mas o resultado exibe os caminhos corretosapenasquando eu me livrar do IFS...
Estou usando o resultado em um for theFile in $i; do......done
loop, ondeos resultados são usados da maneira correta e theFile
exibidos corretamente.
O único problema é que não tenho uma saída correta de console/arquivo $i
, que é um dado estratégico:
O que estou vendo no console e no arquivo que está escrito (amostra):
LecteurSy dicatio _sy dic/fiche_93.xml
O que deve ser exibido e escrito (amostra):
LecteurSyndication_syndic/fiche_93.xml
Qualquer ideia ?
EDIT: roteiro completo para jogar em casa ;)
#!/bin/bash
monTerminal=$(tty) ; monTerminal=${monTerminal:9}
fichier="/home/importts/tmpCmdOpenFirst$monTerminal.xml"
PWD="`pwd`"
echo "== Recherche dans les fiches ==" > "$fichier"
echo "Recherche : $1" >> "$fichier"
echo "Dans : $PWD" >> "$fichier"
OLDIFS=$IFS
IFS="\\n"
i=$(grep -ril $1 *)
echo $i
echo "== Liste des fichiers trouves ==" >> "$fichier"
echo $i >> "$fichier"
IFS=$OLDIFS
#while read uneFiche
for uneFiche in $i;
do
echo "================================" >> "$fichier"
echo "== $uneFiche" >> "$fichier"
echo "================================" >> "$fichier"
echo "" >> "$fichier"
xmlindent "$uneFiche" >> "$fichier"
done < /home/robert/tmpCmdOpenFirst_liste.txt
nano "$fichier"
#rm $fichier
Responder1
Não é fácil seguir a descrição do seu problema. Falta a única informação útil, que é o resultado grep -ril $1 *
(ou melhor, uma amostra disso) e uma explicação do problema. Presumo que o problema seja espaço em branco em alguns caminhos.
EDIT: Aí está a amostra que você solicitou:
Os espaços em branco são de fato 'n' caracteres ...
1_LecteurSy dicatio _sy dic/fiche_174.xml
2_Tra sformatio XSL_tif/fiche_174.xml
3_CorrigerTIF_cor/fiche_174.xml
4_Tra sformatio XSL_ge /fiche_174.xml
/EDITAR
IFS="\\n"
está obviamente errado, pois você pode verificar facilmente com echo "\\n"
. Nem tenho certeza se \n
funciona na definição do IFS. Use IFS=$'\n' em vez disso ou
IFS="
"
EDITAR
O formulário $'\n' não resolve o problema. O formulário "linha em branco" faz com que as coisas apareçam corretamente, mas os resultados não são mais apresentados como uma lista (um por linha). Mantenho o formulário de 'linha em branco', pois o resultado é aproximadamente o que preciso.
/EDITAR
Definir o IFS não faz sentido para mim se você restaurá-lo antes da for uneFiche in $i
linha. Dessa forma você apenas influencia a linha echo $i >> "$fichier"
e teria sido muito mais fácil citar: i="$(grep -ril $1 *)"
,echo "$i" >> "$fichier"
EDITAR
i="$(grep -ril $1 *)"
parece não ter nenhum efeito.
/EDITAR
Se você tiver problemas com espaços em branco e divisão de palavras, talvez seja mais fácil trabalhar com um pipeline como este:
grep -ril --null -- "$1" * | xargs -0 /my/script.sh
com /my/script.sh
ser
#!/bin/bash
fichier="/home/importts/tmpCmdOpenFirst$monTerminal.xml"
for uneFiche in "$@"; do
echo "================================"
echo "== $uneFiche"
echo "================================"
echo
xmlindent "$uneFiche"
done >> "$fichier"
Responder2
Primeiro, você definiu IFS
como \n
, não como uma nova linha. No bash, você pode usar $'…'
sequências de barras invertidas interpretadas como caracteres de controle:
IFS=$'\n'
Ou você tem a opção portátil de usar uma nova linha literal.
IFS='
'
O segundo problema é IFS
importante quando você expande uma variável. Portanto, ele precisa ser definido quando $i
for expandido; na verdade, não importa quando você define i
.
i=$(grep -ril -e "$1" -- *)
set -f; OLDIFS="$IFS"; IFS='
'
for uneFiche in $i; do
set +f; IFS="$OLDIFS"
…
done
set +f; IFS="$OLDIFS"
Além disso, não se esqueça de citar variáveis quando não estiver dividindo, por exemplo, o padrão para o qual você passa grep
. Caso o padrão comece com -
, passe-o para grep
com a -e
opção. Coloque também --
na frente dos nomes dos arquivos, caso o primeiro nome do arquivo comece com -
. Além disso, caso um nome de arquivo contenha caracteres glob, desative globbing com set -f
antes de deixar uma expansão de variável sem aspas.
Uma abordagem mais simples seria chamar grep
cada arquivo dentro do loop. Como um benefício adicional, seu script não quebraria em nomes de arquivos contendo novas linhas.
for uneFiche in *; do
if grep -qri -e "$1" -- "$uneFiche"; then
…
fi
done
Responder3
Aí está o roteiro final que funciona, graças a Gilles:
#!/bin/bash
# use a buffer file per terminal, permits multiple users
monTerminal=$(tty) ; monTerminal=${monTerminal:9}
fichier="........./tmpCmdFiche$monTerminal.xml"
PWD="`pwd`"
echo "== Recherche dans les fiches ==" > "$fichier"
echo "Recherche : $1" >> "$fichier"
echo "Dans : $PWD" >> "$fichier"
i=$(grep -ril -e "$1" -- *)
set -f
OLDIFS="$IFS"
IFS='
'
echo "== Liste des fichiers trouves ==" >> "$fichier"
echo "$i" >> "$fichier"
for uneFiche in $i; do
set +f; IFS="$OLDIFS"
echo "================================" >> "$fichier"
echo "== $uneFiche" >> "$fichier"
echo "================================" >> "$fichier"
echo "" >> "$fichier"
xmlindent "$uneFiche" >> "$fichier"
done < ............/tmpCmdOpenFirst_liste.txt
set +f
IFS="$OLDIFS"
E então uma amostra do cmdFiche somethingsosearch
resultado do comando:
== Recherche dans les fiches ==
Recherche : somethingsosearch
Dans : ............/XMLs/.........
== Liste des fichiers trouves ==
1_ImportationZip_zip/file2.xml
2_ImportationSuppSyndication_syndic/file19.xml
3_ModifierOrdreImages_ordre/fiche_44.xml
4_CorrigerPeriodesViaSyndication_periodes/fiche_44.xml
5_TransformationXSL_tif/fiche_44.xml
6_CorrigerRaisonSocialeViaSyndic_raisonsociale/fiche_44.xml
7_ExclureImportNoeuds_avantv2/fiche_44.xml
================================
== 1_ImportationZip_zip/file2.xml
================================
<?xml version="1.0" encoding="utf-8"?>
<tif:OI xmlns:tif="http://www.tourinfrance.net/Tourinfrance3/" xmlns:xsi="http://www.w$
<!--Granule DublinCore-->
<tif:DublinCore>
Incrível !