Сценарий оболочки - поиск и текст замены в нескольких файлах с помощью списка строк

Класс Model реализует интерфейс Arrayable, это означает, что вы можете получить доступ к атрибутам также, как если бы это был array, вот почему эта работа:

$reply->thread['title'];

Когда вы используйте отношение BelongsTo, ожидаемое возвращение объекта (экземпляра вашей модели) или null в случае, если это отношение не установлено, поэтому вы можете использовать «магические методы» для доступа к таким атрибутам: [ 1119]

$reply->thread // an object
$reply->thread->title // getting attributes using magic methods

Но что происходит, когда отношения не установлены? что ж, отношения вернутся null, поэтому, когда вы сделаете это:

$reply->thread->title

Это вызовет ошибку:

Попытка получить заголовок свойства не-объекта [1122 ] blockquote>

Поскольку вы пытаетесь получить доступ к атрибуту title в null.


Обновление:

Здесь, я думаю, ошибка. В новейшей версии Laravel (на сегодняшний день: Laravel 5.8) типы ключей первичных ключей изменились с integers на bigIntegers(), и это для всех таблиц:

Schema::create('replies', function (Blueprint $table)
{
    $table->bigIncrements('id'); // <---- equivalent to bigInteger
    $table->integer('user_id')->unsigned;
    $table->integer('thread_id')->unsigned;
    $table->text('body');
    $table->timestamps();
});

Так Ваши внешние ключи должны быть также большими целыми числами, попробуйте это:

Schema::create('replies', function (Blueprint $table)
{
    $table->bigIncrements('id');
    $table->unsignedBigInteger('user_id'); // <-----------
    $table->unsignedBigInteger('thread_id'); // <-----------
    $table->text('body');
    $table->timestamps();
});

Проверьте , эта статья связана с этой проблемой.

8
задан aschipfl 6 June 2019 в 17:11
поделиться

3 ответа

Вот основные шаги, которые я сделал бы

  1. Скопируйте файл changesDictionary.txt
  2. В нем заменяют "a" = "b" к эквивалентной sed строке: например, (используют 1$ для имени файла),

    sed-e 's/a/b/g' 1$

    (Вы могли записать сценарий, чтобы сделать это или просто сделать это вручную, если просто необходимо сделать это однажды, и это не является слишком большим).

  3. Если файлы - все в одном каталоге, то можно сделать что-то как:

    ls *.txt | xargs scriptFromStep2.sh

  4. Если они находятся в subdirs, используйте находку для вызова того сценария на всех файлах, чем-то как

    найти. - называют '*.txt' - должностное лицо scriptFromStep2.sh {} \;

Они не точны, сделайте некоторые эксперименты, чтобы удостовериться, что Вы разбираетесь в нем - это - просто подход, который я использовал бы.

(но, если бы Вы можете, просто использовать жемчуг, это было бы намного более просто),

5
ответ дан 5 December 2019 в 12:13
поделиться

Я преобразовал бы Ваш файл changesDictionary.txt в sed сценарий, с... sed:

$ sed -e 's/^"\(.*\)" = "\(.*\)"$/s\/\1\/\2\/g/' \
      changesDictionary.txt  > changesDictionary.sed

Отметьте, любые специальные символы или для регулярных выражений или для sed выражений в Вашем словаре будут ложно интерпретироваться sed, таким образом, Ваш словарь сможет или только иметь только самый примитивный поиск-и-замены, или необходимо будет поддержать sed файл с допустимыми выражениями. К сожалению, нет никакого простого способа в sed, чтобы или отключить регулярное выражение и использовать только сопоставление строк или заключить в кавычки Ваши поиски и замены как "литералы".

С получающимся sed сценарием использование находит и xargs - а не находит - должностное лицо - преобразовывать Ваши файлы с sed сценарием как можно быстрее путем обработки их больше, чем по одному.

$ find somedir -type f -print0 \
   | xargs -0 sed -i -f changesDictionary.sed

Отметьте, -i опция sed редактирует "оперативные" файлы, так убедиться сделать резервные копии для безопасности или использование -i~ создать резервные копии тильды.

Заключительное примечание, с помощью поиска и замен может иметь непреднамеренные последствия. У Вас будут поиски, которые являются подстроками других поисков? Вот пример.

$ cat changesDictionary.txt
"fix" = "broken"
"fixThat" = "Fixed"
$ sed -e 's/^"\(.*\)" = "\(.*\)"$/s\/\1\/\2\/g/' changesDictionary.txt  \
   | tee changesDictionary.sed
s/fix/broken/g
s/fixThat/Fixed/g
$ mkdir subdir
$ echo fixThat > subdir/target.txt
$ find subdir -type f -name '*.txt' -print0 \
   | xargs -0 sed -i -f changesDictionary.sed
$ cat subdir/target.txt
brokenThat

"fixThat" должен был стать "Фиксированным" или "brokenThat"? Порядок имеет значение для sed сценария. Точно так же поиск и замена могут быть поиском и замененный несколько раз - изменяющийся "a" к "b", может быть изменен другим поиском-и-заменой позже от "b" до "c".

Возможно, Вы уже рассмотрели оба из них, но я упоминаю, потому что я попробовал то, что Вы делали прежде и не думали о нем. Я не знаю ни о чем, что просто делает правильную вещь для того, чтобы сделать, несколько ищут и замены сразу. Так, необходимо программировать его, чтобы сделать правильную вещь сами.

6
ответ дан 5 December 2019 в 12:13
поделиться
#!/bin/bash
f="changesDictionary.tx"
find /path -type f -name "*.txt" | while read FILE 
do
    awk 'BEGIN{ FS="=" }
    FNR==NR{ s[$1]=$2;  next }
    {
       for(i in s){      
        if( $0 ~ i ){ gsub(i,s[i]) }
       }
       print $0
    }' $f $FILE  > temp
    mv temp $FILE
done
1
ответ дан 5 December 2019 в 12:13
поделиться
Другие вопросы по тегам:

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