У меня есть файл журнала, который нужно проанализировать и проанализировать. Файл содержит нечто подобное, как показано ниже:
Файл:
20141101 server contain dump
20141101 server contain nothing
{uekdmsam ikdas
jwdjamc ksadkek} ssfjddkc * kdlsdl
sddsfd jfkdfk
20141101 server contain dump
Исходя из описанного выше сценария, я должен проверить, не содержит ли начальная строка дату или номер, который я должен добавить к предыдущей строке.
Выходной файл:
20141101 server contain dump
20141101 server contain nothing {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdl sddsfd jfkdfk
20141101 server contain dump
text-processing
sed
awk
Уильям Р
источник
источник
-0
если для записей, разделенных NUL. Используйте,-0777
чтобы выплеснуть весь файл в память (который вам здесь не нужен).Может быть немного легко с
sed
первая часть
:1;N;$!b1
собрать все строки в файле, разделенные на\n
1 длинную строкувторая часть убирает символ новой строки, если он следует за нецифровым символом с возможными пробелами между его.
Чтобы избежать ограничения памяти (особенно для больших файлов), вы можете использовать:
Или забыть сложные
sed
сценарии и помнить, что год начинается с2
источник
tr '\n' $'\a' | sed $'s/\a\a*\( *[^0-9]\)/\1/g' | tr $'\a' '\n'
сам.+
есть\{1,\}
.[\n]
тоже не портативно.\n\{1,\}
будет POSIX.: 1;x
является определение1;x
метки в POSIX seds. Так что вам нужно:sed -e :1 -e 'N;$!b1' -e 's/\n\{1,\}\( *[^0-9]\)/\1/g'
. Также обратите внимание, что многиеsed
реализации имеют небольшое ограничение на размер своего шаблонного пространства (POSIX гарантирует только 10 x LINE_MAX IIRC).Одним из способов будет:
Однако, это также удаляет заключительный перевод строки. Чтобы добавить его снова, используйте:
объяснение
Он
-l
удалит завершающие символы новой строки (а также добавит одну к каждомуprint
вызову, поэтому я используюprintf
вместо этого. Затем, если текущая строка начинается с цифр (/^\d+/
), а номер текущей строки больше единицы ($.>1
это необходимо, чтобы избежать добавления дополнительных пустая строка в начале), добавьте\n
в начало строкиprintf
.Печатает каждую строку.Кроме того, вы можете изменить все
\n
символы на\0
, а затем изменить те,\0
которые находятся прямо перед строкой чисел,\n
снова:Чтобы он соответствовал только строкам из 8 чисел, используйте вместо этого:
источник
printf
это формат . Использованиеprintf "%s", $_
%10000000000s
например.perl
,echo %.10000000000f | perl -ne printf
ставит мою машину на колени.Попробуйте сделать это с помощью awk :
Чтобы использовать это:
источник
Другой простой способ (чем мой другой ответ) с использованием алгоритма awk и terdon :
источник
END{print ""}
. Альтернатива:awk -v ORS= 'NR>1 && /^[0-9]{8}/{print "\n"};1;END{print "\n"}'
источник
Le program en bash:
в однострочном виде:
Решение с сохранением обратной косой черты (
read -r
) и пробелами (сразуIFS=
послеwhile
):однострочная форма:
источник
n
. Это также удаляет пробелы. Но вы можете использоватьmksh
для этого:while IFS= read -r L; do [[ $L = [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]* ]] && print; print -nr -- "$L"; done; print
Это будет работать
источник