Comportamiento muy extraño con grep e IFS

Comportamiento muy extraño con grep e IFS

Tengo problemas para usar grep, los resultados devueltos son "n-vacíos", es decir, sin el carácter 'n'...

Este es el ejemplo del script:

OLDIFS=$IFS
IFS="\\n"

i=$(grep -ril $1 *)

echo $i

IFS=$OLDIFS

Lo intenté con IFS='\n'y IFS="\n"pero el resultado muestra las rutas correctas.solocuando me deshago del IFS...

Estoy usando el resultado en un for theFile in $i; do......donebucle, dondelos resultados se utilizan de la manera correcta y theFilese muestran correctamente.

El único problema es que no tengo una salida de archivo/consola correcta $i, que es un dato estratégico:

Lo que estoy viendo en la consola y el archivo que está escrito (muestra):

LecteurSy dicatio _sy dic/fiche_93.xml

Qué se debe mostrar y escribir (muestra):

LecteurSyndication_syndic/fiche_93.xml

Alguna idea ?

EDITAR: guión completo para jugar en 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

Respuesta1

No es fácil seguir la descripción de su problema. La única información útil que falta es el resultado grep -ril $1 *(o más bien una muestra de eso) y una explicación de cuál es el problema. Supongo que el problema son los espacios en blanco en algunas rutas.

EDITAR: Ahí está la muestra que solicitó:

Los espacios en blanco son de hecho '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"obviamente está mal, como puede comprobarlo fácilmente con echo "\\n". Ni siquiera estoy seguro de si \nfunciona según la definición de IFS. Utilice IFS=$'\n' en su lugar o

IFS="
"

EDITAR

El formulario $'\n' no resuelve el problema. El formulario de "línea en blanco" hace que las cosas aparezcan correctamente, pero los resultados ya no se presentan como una lista (una por línea). Mantengo el formulario de 'línea en blanco' ya que su resultado es aproximadamente lo que necesito.

/EDITAR

Configurar IFS no tiene sentido para mí si lo restaura antes de la for uneFiche in $ilínea. De esta manera simplemente influyes en la línea echo $i >> "$fichier"y hubiera sido mucho más fácil citando: i="$(grep -ril $1 *)",echo "$i" >> "$fichier"

EDITAR

i="$(grep -ril $1 *)"parece no tener ningún efecto.

/EDITAR

Si tiene problemas con los espacios en blanco y la división de palabras, entonces podría ser más fácil trabajar con una canalización como esta:

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

con /my/script.shser

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

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

xmlindent "$uneFiche"

done >> "$fichier"

Respuesta2

Primero, lo ha configurado IFSen \n, no en una nueva línea. En bash, puedes usar $'…'secuencias de barras invertidas interpretadas como caracteres de control:

IFS=$'\n'

O tiene la opción portátil de utilizar una nueva línea literal.

IFS='
'

El segundo problema es que IFSimporta cuando expandes una variable. Por lo tanto, es necesario configurar cuándo $ise expande; en realidad, no importa cuándo se configura 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"

Además, no olvide citar las variables cuando no esté dividiendo, por ejemplo, el patrón al que pasa grep. En caso de que el patrón comience con -, páselo a grepcon la -eopción. También colóquelo --delante de los nombres de los archivos en caso de que el primer nombre de archivo comience con -. Además, en caso de que el nombre de un archivo contenga caracteres globales, desactívelos set -fantes de dejar una expansión variable sin comillas.

Un enfoque más sencillo sería llamar grepa cada archivo dentro del bucle. Como beneficio adicional, su secuencia de comandos no se interrumpirá en nombres de archivos que contengan nuevas líneas.

for uneFiche in *; do
  if grep -qri -e "$1" -- "$uneFiche"; then
  fi
done

Respuesta3

Ahí está el guión final que funciona, gracias 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"

Y luego una muestra del cmdFiche somethingsosearchresultado del 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>

Impresionante !

información relacionada