Очень странное поведение с 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> 

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

  • У меня есть многострочная строка, которую мне нужно перебрать, но я не использую bash. Совет?
  • Как я могу автоматически вводить пароль из .bash_profile при запуске команды в качестве sudo?
  • Подключение через telnet и выполнение определенных операций
  • Поток FFMPEG не появится на Justin.tv
  • как проверить, установлены ли оба параметра в bash?
  • Ошибка при вызове скрипта из другого скрипта
  • Сценарий оболочки для удаления всех файлов, которые являются более старыми
  • Записать вывод оболочки в документ MS Word
  • Вставить
  • Awk для печати только соответствующего слова
  • Рассчитать количество дней оплаты
  • Interesting Posts

    Какова цель оболочки uucico на HP-UX, Solaris и, возможно, других Unix-разновидностях?

    Как настроить групповое разрешение для разных пользователей на нескольких установках Linux?

    Где я могу найти файл конфигурации для uw-imapd на debian?

    Передача файлов с помощью SSH и переключателя

    Как очистить / перезагрузить смарт-аккумулятор?

    Использование вывода команды для определения имени файла для перенаправления вывода на

    Серии файлов BIND – уникальные для всех зон или только для себя?

    Трассировка пакета в сетевом стеке Linux

    Невозможно изменить пароль linux

    Как сконфигурировать имя устройства для шифрования корневого раздела с Grub2?

    Объединение операторов awk

    Как увеличить число панелей tmux отображает время `ctrl-b q`

    Как отобразить Thunderbird в меню

    Где я могу проверить, что было обновлено в последнем обновлении?

    Использование rsync для резервного копирования 4 разных VPS на пятый VPS, который использует для хранения резервных копий

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