Поиск и замена строки на определенных расширениях файла

Я не знаю о несправедливости, но это является, конечно, замысловатым. Если Ваши входные строки похожи на это:

YYYY-MM-DD some text ...

Затем нет действительно никакой причины этого:

new_file=${line:0:4}-${line:5:2}-${line:8:2}_file.log

Вы делаете большую работу подстроки для окончания с чем-то, что смотрит... точно способ, которым это уже смотрит в файле. Как насчет этого?

while read line; do
  new_file="${line:0:10}_file.log"
  echo "$line" >> $new_file
done

Это просто захватывает первые 10 символов от строки. Вы могли также обойтись без bash полностью и просто используйте awk:

awk '{print > ($1 "_file.log")}' < file.log

Это захватывает дату в $1 (первый разграниченный пробелом столбец в каждой строке) и использование это для генерации имени файла.

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

awk '
$1 ~ /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/ {
    print > ($1 "_file.log")
    next
}

{
    print "INVALID:", $0
}
'

Это пишет соответствие строк YYYY-MM-DD к Вашим файлам журнала и строкам флагов, которые не запускаются с метки времени на stdout.

4
08.01.2013, 02:11
2 ответа

Можно использовать -name опция для находки для ограничения соответствий на основе имени файла.

find myDirectory/. -type f -name '*.txt' -print0 | xargs -0 sed -i "$replace"

Для нескольких расширений можно использовать -o (или) и группа их с ().

find myDirectory/. -type f \( -name '*.txt' -o -name '*.read' \) -print0 | xargs -0 sed -i "$replace"

Другое улучшение, которое может быть сделано, использует -exec вместо xargs. Это более портативно и устраняет подоболочку.

find myDirectory/. -type f -name '*.txt' -exec sed -i "$replace" {} +
10
27.01.2020, 20:47
  • 1
    2-я опция, работающая на меня... спасибо!!! –  SpaceDog 07.01.2013, 04:27
  • 2
    Для любого поиск с помощью Google, для выполнения последней строки в этом ответе без переменной, вот является примером, который рекурсивно находит все txt файлы с нечто и замены панелью. Включайте знак "плюс" в конец: find ./ -type f -name '*.txt' -readable -writable -exec sed -i "s/foo/bar/g" {} + –  degenerate 20.10.2017, 17:27

Добавьте эти настройки к Вашему .bashrc:

shopt -s extglob globstar

extglob включает некоторые дополнительные шаблоны, включая @(…) создайте для разъединения. globstar включает **/ который пересекает каталоги рекурсивно.

Затем Вы не должны использовать find:

sed -i "$replace" mydirectory/**/*.@(txt|read|po)

В zsh Вы не нуждаетесь ни в какой специальной опции, просто работаете

sed -i $replace mydirectory/**/*.(txt|read|po)

Если у Вас есть много файлов, можно видеть, что сообщение как “предел длины командной строки превысило”. Но предел очень высок в современных системах Linux, Вы вряд ли встретитесь с ним.

4
27.01.2020, 20:47
  • 1
    I upvoted вопрос, потому что я ценю globbing, но это кажется излишеством, чтобы попросить, чтобы кто-то изменил .bashrc для единственной команды. Почему не только устанавливает его перед командой и дополнительно сбросом впоследствии? Если бы пользователь хочет установку постоянно, которая была бы отдельным вопросом. –  user1404316 29.01.2018, 17:28
  • 2
    Кроме того, extglob действительно необходимый? Не может то же быть выполненным со стандартным расширением фигурной скобки, т.е. {txt,read,po}вместо @(txt|read|po)? –  user1404316 29.01.2018, 20:17
  • 3
    @user1404316 только работают, если существует по крайней мере один файл с каждым расширением. Иначе соответствующий шаблон шарика останется неизменным. Например, если текущий каталог содержит hello.world, foo.txt, bar.txt, messages.po только, затем cat *.(txt|read|po) эквивалентно cat messages.po bar.txt foo.txt (единственный шаблон шарика, расширяется в лексикографическом порядке), в то время как cat *.{txt,read,po} расширяется до cat bar.txt foo.txt *.read messages.po и кошка будет жаловаться, что нет никакого названного файла *.read. –  Gilles 'SO- stop being evil' 30.01.2018, 01:11

Теги

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