Мне нужно написать скрипт, который проверяет несколько файлов >20k на поиск текста >2k, и он должен быть гибким, поэтому я придумал этот скрипт:
#!/bin/bash
# This script checks all files in a given directory against a list of criteria
shopt -s expand_aliases
source ~/.bashrc
TIMESTAMP=$(date "+%Y-%m-%d-%T")
ROOT_DIR=/data
PROJECT_NAME=$1
FILE_DIR=$ROOT_DIR/projects/$1/$2
RESULT_DIR=$ROOT_DIR/projects/$1/check_result
SEARCHTEXT_FILE=$ROOT_DIR/scripts/$3
OIFS = "$IFS"
IFS=$'\n'
files=$(find $FILE_DIR -type f -name '*.json')
for file in $files; do
while read line; do
grep -H -o $line "$file" >> $RESULT_DIR/check_result_$TIMESTAMP.log
done < $SEARCHTEXT_FILE
done
IFS = "$OIFS"
Этот скрипт создает только пустой файл журнала $RESULT_DIR/check_result_$TIMESTAMP.log
с правильным именем.
Поскольку имена файлов иногда содержат пробелы, я добавил операторы IFS... и заключил $file в кавычки (скопировано из другого поста).
Содержание $SEARCHTEXT_FILE
, например:
'Tel alt........'
'City ..........'
Если я поставлю эхо перед grep, как это
echo grep -H -o $line "$file"
тогда вывод, который я получаю,
grep -H -o 'Tel alt........' /data/projects/DNAR/input/report-157538.json
и я могу выполнить эту строку как есть и получить правильный результат.
Я пытался поместить различные комбинации " или ' или ` или () или {} вокруг любой части этой команды grep, но ничего не изменилось. Где-то я читал о псевдониме, и псевдоним, установленный для grep,
alias grep='grep --color=auto'
После многих часов поиска в Интернете я не смог найти ни одного сообщения, которое помогло бы мне, так как большинство из них освещают проблемы, связанные с неправильными кавычками или встроенными проблемами bash. Что мне здесь не хватает?
Я использовал dos2unix для всех файлов, а также редактировал файлы в vi, но ничего не изменилось.
Был удаленный комментарий, который, я думаю, объяснял, как ваш цикл работал grep
на неправильных вещах, но я не изучил сценарий достаточно подробно, чтобы сказать, действительно ли это объясняет отсутствие вывода. Я, конечно, также подумал, что вы, вероятно, путаете свои аргументы в этом цикле, но трудно сказать, когда мы не можем видеть содержимое файла или структуру каталогов, с которыми он должен работать.
Простой и очевидный обходной путь — убрать всю эту сложность и просто использовать функции команд, которые вы все равно запускаете.
find "$FILE_DIR" -type f -name '*.json' \
-exec grep -H -o -f "$SEARCHTEXT_FILE" {} + > "$RESULT_DIR/check_result_$TIMESTAMP.log"
Обратите также внимание на исправления цитирования; см. Когда заключать переменную оболочки в кавычки ; чтобы избежать ошибок, вам следует переключиться на нижний регистр для ваших частных переменных (см. Правильный ввод переменных в сценариях Bash и shell).
shopt -s expand_aliases
и source ~/.bashrc
просто выглядят излишними, но могут способствовать возникновению любой проблемы, которую вы пытаетесь устранить; в принципе, они никогда не должны быть частью сценария, который вы планируете использовать в производстве.
Спасибо за ваш ответ, я скорректировал сценарий и изменил его выше, но он все равно не дает желаемого результата.
Попробуйте сократить до минимального воспроизводимого примера с помощью нескольких файлов примеров. Например, вот так: ideone.com/ONdj9V
Теперь я также удалил кавычки в файле $ SEARCHTEXT_FILE, и теперь это работает. Спасибо
Ах, я хотел спросить об этом, но забыл!
Я предполагаю, что ваш входной файл содержит перевод строки DOS, но без дополнительной диагностики трудно сказать. Смотрите также stackoverflow.com/questions/39527571/…