Очень странное поведение с grep и IFS

У меня возникли проблемы с использованием grep, возвращаемые результаты «n-empty», я имею в виду без символа «n» …

Это пример скрипта:

OLDIFS=$IFS IFS="\\n" i=$(grep -ril $1 *) echo $i IFS=$OLDIFS 

Я пробовал с IFS='\n' и IFS="\n" но результат отображает правильные пути только тогда, когда я избавляюсь от IFS …

Я использую результат в a for theFile in $i; do......done for theFile in $i; do......done loop, где результаты используются правильно, и theFile правильно отображается .

Единственная проблема заключается в том, что у меня нет правильного вывода консоли / файла из $i , который является стратегическим:

Что я вижу в консоли и файл, который написан (образец):

LecteurSy dicatio _sy dic/fiche_93.xml

Что должно отображаться и записываться (образец):

LecteurSyndication_syndic/fiche_93.xml

Есть идеи ?

EDIT: полный скрипт, чтобы играть дома;)

 #!/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 

3 Solutions collect form web for “Очень странное поведение с grep и IFS”

Во-первых, вы установили IFS в \n , а не в новую строку. В bash вы можете использовать $'…' чтобы иметь последовательности обратной косой черты, интерпретируемые как управляющие символы:

 IFS=$'\n' 

Или у вас есть переносная опция использования литеральной новой строки.

 IFS=' ' 

Вторая проблема заключается в том, что IFS имеет значение, когда вы расширяете переменную. Поэтому его необходимо установить, когда $i расширяется, на самом деле это не имеет значения, когда вы устанавливаете 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" 

Кроме того, не забудьте указать переменные, если вы не раскалываете, например шаблон, который вы передаете grep . Если шаблон начинается с - , передайте его в grep с параметром -e . Также помещайте -- перед именами файлов в случае, если первое имя файла начинается с - . Кроме того, если имя файла содержит символы glob, отключите globbing с помощью set -f прежде чем оставить расширение переменной без кавычек.

Более простой подход состоял бы в вызове grep для каждого файла внутри цикла. В качестве дополнительного преимущества ваш скрипт не будет разбиваться на имена файлов, содержащие новые строки.

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

Непросто следовать описанию проблемы. Единственная полезная информация отсутствует, то есть вывод grep -ril $1 * (или, скорее, образец этого) и объяснение проблемы. Я предполагаю, что проблема – это пробел в некоторых путях.

РЕДАКТИРОВАТЬ: есть образец, который вы запросили:

Заготовки действительно являются «n» символами …

 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 

/РЕДАКТИРОВАТЬ

IFS="\\n" явно ошибочно, поскольку вы можете легко проверить с помощью echo "\\n" . Я даже не уверен, работает ли \n в определении IFS. Используйте IFS = $ '\ n' вместо или

 IFS=" " 

РЕДАКТИРОВАТЬ

Форма $ '\ n' не решает проблему. Форма «пустая строка» делает вещи правильными, но результаты больше не представлены в виде списка (по одной в строке). Я сохраняю форму «пустая строка», так как ее результат примерно соответствует мне.

/РЕДАКТИРОВАТЬ

Установка IFS не имеет смысла для меня, если вы восстановите ее до того, for uneFiche in $i строке for uneFiche in $i . Таким образом, вы просто echo $i >> "$fichier" на строку echo $i >> "$fichier" и это было бы намного проще, указав: i="$(grep -ril $1 *)" , echo "$i" >> "$fichier"

РЕДАКТИРОВАТЬ

i="$(grep -ril $1 *)" похоже, не имеет никакого эффекта.

/РЕДАКТИРОВАТЬ

Если у вас есть такие проблемы с пробелом и разбиением слов, может быть проще работать с конвейером следующим образом:

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

с /my/script.sh

 #!/bin/bash fichier="/home/importts/tmpCmdOpenFirst$monTerminal.xml" for uneFiche in "$@"; do echo "================================" echo "== $uneFiche" echo "================================" echo xmlindent "$uneFiche" done >> "$fichier" 

Существует окончательный сценарий, который работает, благодаря Жилю:

 #!/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" 

И затем образец команды 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> 

Потрясающие !

  • Сценарий оболочки для добавления разных данных GPS в серии фотографий
  • bash - источник, не загрязняя собственное пространство имен
  • Фильтрация изображений в соответствии с именем файла, почему?
  • Поиск и замена с помощью sed
  • сумма всех пакетов в файлах pcap
  • Сценарий Bash для запуска виртуальной среды python не выполняется
  • Запретить выполнение в домашнем каталоге
  • Оптимизированный способ отображения и удаления файлов
  • Пытаться направить содержимое переменной в команду дает Ambigious Redirect
  • Переадресация переменной bash в netcat
  • Как назначить слова с пробелами как целое имя переменной в сценарии оболочки?
  • Interesting Posts

    распаковка tarball с жесткими ссылками на файловую систему, которая не поддерживает жесткие ссылки

    Как получить USB накопитель Seagate 2 ТБ?

    Как я могу заставить GRUB правильно настроить экран?

    Используйте некоторый загрузчик EFI для загрузки MBR

    Самый безобидный пакет для установки для тестирования yum?

    LFSH … для чего / lib / init?

    Raspberry Pi 2 работает на raspbian, так как каждый раз он отключает внешний жесткий диск

    мертвый ключ после переключения двух клавиш с помощью xmodmap

    Доступ к памяти через плоский файл в Linux

    Как определить, когда оболочка принадлежит удаленному сеансу SSH?

    Как запустить два потока в сценарии оболочки bash?

    Когда Samba работал в manjoro linux, демону не удалось запустить: Samba обнаружила неправильно сконфигурированную «роль сервера» и вышла.

    Нет загрузочного меню с Linux Mint и Windows 7

    Как устранить то, что ест память?

    Поиск файлов по всей стране, созданных в диапазоне дат

    Linux и Unix - лучшая ОС в мире.