Я не знаю о несправедливости, но это является, конечно, замысловатым. Если Ваши входные строки похожи на это:
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.
Можно использовать -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" {} +
Добавьте эти настройки к Вашему .bashrc
:
shopt -s extglob globstar
extglob
включает некоторые дополнительные шаблоны, включая @(…)
создайте для разъединения. globstar
включает **/
который пересекает каталоги рекурсивно.
Затем Вы не должны использовать find
:
sed -i "$replace" mydirectory/**/*.@(txt|read|po)
В zsh Вы не нуждаетесь ни в какой специальной опции, просто работаете
sed -i $replace mydirectory/**/*.(txt|read|po)
Если у Вас есть много файлов, можно видеть, что сообщение как “предел длины командной строки превысило”. Но предел очень высок в современных системах Linux, Вы вряд ли встретитесь с ним.
.bashrc
для единственной команды. Почему не только устанавливает его перед командой и дополнительно сбросом впоследствии? Если бы пользователь хочет установку постоянно, которая была бы отдельным вопросом.
– user1404316
29.01.2018, 17:28
extglob
действительно необходимый? Не может то же быть выполненным со стандартным расширением фигурной скобки, т.е. {txt,read,po}
вместо @(txt|read|po)
?
– user1404316
29.01.2018, 20:17
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
find ./ -type f -name '*.txt' -readable -writable -exec sed -i "s/foo/bar/g" {} +
– degenerate 20.10.2017, 17:27