Comportamento muito estranho com grep e IFS

2

Estou tendo problemas para usar o grep, os resultados retornados são "n-empty", 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 corretos somente quando eu me livrei do IFS ...

Estou usando o resultado em um loop for theFile in $i; do......done , em que os resultados são usados da maneira correta e theFile é exibido corretamente .

O único problema é que não tenho saída correta de console / arquivo de $i , que é um dado estratégico:

O que estou vendo no console e o 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

Alguma ideia?

EDIT: script 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
    
por Benj 26.04.2013 / 14:15

3 respostas

1

Primeiro, você definiu IFS para \n , não para uma nova linha. No bash, você pode usar $'…' para ter seqüências de backslash 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 é que IFS é importante quando você expande uma variável. Portanto, é necessário definir quando $i é expandido, mas 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 que você passa para grep . Caso o padrão comece com - , passe-o para grep com a opção -e . Coloque também -- na frente dos nomes dos arquivos, caso o primeiro nome de arquivo comece com - . Além disso, caso um nome de arquivo contenha caracteres glob, desative a globbing com set -f antes de deixar uma expansão variável sem aspas.

Uma abordagem mais simples seria chamar grep em cada arquivo dentro do loop. Como 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
    
por 28.04.2013 / 02:01
2

Não é fácil seguir a descrição do seu problema. A única informação útil está faltando, que é a saída de grep -ril $1 * (ou melhor, uma amostra disso) e uma explicação sobre qual é o problema. Eu assumo que o problema é espaço em branco em alguns caminhos.

EDIT: Existe o exemplo que você solicitou:

Os espaços em branco são de fato 'n' chars ...

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

/ EDIT

IFS="\n" está obviamente errado, pois você pode verificar facilmente com echo "\n" . Eu não 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). Eu mantenho o formulário de 'linha em branco' já que seu resultado é aproximadamente o que eu preciso.

/ EDIT

A configuração do IFS não faz sentido para mim se você restaurá-lo antes da linha for uneFiche in $i . Desta forma você apenas influencia a linha echo $i >> "$fichier" e isso seria muito mais fácil citando: i="$(grep -ril $1 *)" , echo "$i" >> "$fichier"

EDITAR

i="$(grep -ril $1 *)" parece não ter nenhum efeito.

/ EDIT

Se você tiver problemas com espaço em branco e divisão de palavras, talvez seja mais fácil trabalhar com um canal como este:

grep -ril --null -- "$1" * | xargs -0 /my/script.sh

com /my/script.sh sendo

#!/bin/bash
fichier="/home/importts/tmpCmdOpenFirst$monTerminal.xml"

for uneFiche in "$@"; do
    echo "================================"
    echo "== $uneFiche"
    echo "================================"
    echo

xmlindent "$uneFiche"

done >> "$fichier"
    
por 26.04.2013 / 15:46
0

Existe o script 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, em seguida, uma amostra do resultado do comando cmdFiche somethingsosearch :

== 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!

    
por 30.04.2013 / 10:15