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

Вот разбивка

if [ `sdptool browse $BD_ADDR | wc -l` -lt 5 ]
  1. if: начало оператора "if" оболочки
  2. [: это - на самом деле команда. Это - псевдоним для test команда
  3. ': это - начало замены команды
  4. sdptool browse $BD_ADDR | wc -l: возвращает количество строк, произведенных sdptool
  5. ': конец замены команды
  6. -lt 5: это - аргумент test команда упоминается ранее. Вывод замены команды (количество строк, произведенных sdptool) сравнивается 5 и возвраты true если меньше или false иначе
2
28.04.2013, 03:02
3 ответа

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

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 опция. Также помещенный -- перед именами файлов в случае, если первое имя файла начинается -. Кроме того, в случае, если имя файла содержит символы шарика, выключите globbing с set -f прежде, чем оставить переменное расширение закрыло кавычки.

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

for uneFiche in *; do
  if grep -qri -e "$1" -- "$uneFiche"; then
    …
  fi
done
1
27.01.2020, 22:06
  • 1
    , который я не понимаю, почему Вы используете set +f; IFS="$OLDIFS" в цикле: это имеет какой-либо эффект? –  Benj 29.04.2013, 13:39
  • 2
    @Benj В случае, если подстановочное расширение или IFS используется в цикле (не случай здесь, но они могли быть то, если код развивается). Я также сбросил их после цикла в случае, если расширение, оказывается, пусто. –  Gilles 'SO- stop being evil' 29.04.2013, 14:12
  • 3
    , я выслал редактирование, которое я сделал в отдельном ответе, я думаю, что это более читаемо. Можно удалить редактирование, которое я сделал к ответу, или сообщите мне то, что является более читаемым путем. –  Benj 30.04.2013, 11:17

Не легко следовать за Вашим описанием проблемы. Единственная полезная информация отсутствует, который является выводом 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 строка. Таким образом, Вы просто влияете на строку 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"
2
27.01.2020, 22:06
  • 1
    на @HaukeLaging, Так как Ваш ответ довольно последователен, я ответил путем редактирования его, шаг за шагом. –  Benj 26.04.2013, 17:43
  • 2
    @Benj нет, нет... Я подразумевал, что необходимо было запустить с проблемы, которую Вы собирались решить. Вашей начальной проблемой едва были пропавшие без вести "n", которые являются результатом Вашей пробной версии для решения бывшей проблемы. Таким образом что относительно вывода, если Вы используете кавычки, когда я показал Вам? –  Hauke Laging 26.04.2013, 17:51
  • 3
    echo образец я вставил первое Редактирование, является прямым echo из $i. Я очень ценю Вашу справку, спасибо :). –  Benj 26.04.2013, 17:54
  • 4
    @Benj, Конечно, заключая в кавычки в одном месте не изменяет результат. Не имеет значения, где разделение слова происходит. Необходимо заключить оба случая в кавычки, i= и echo. –  Hauke Laging 26.04.2013, 17:58
  • 5
    Хорошо, я не знал об этом. –  Benj 29.04.2013, 13:36

Существует заключительный сценарий, который работает благодаря 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"

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

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

0
27.01.2020, 22:06

Теги

Похожие вопросы