Как добавить Строку к предыдущей Строке?

Можно использовать единственную обратную галочку ('ключ)

9
21.11.2018, 23:27
7 ответов

Версия в perl, используя отрицательные форумы:

$ perl -0pe 's/\n(?!([0-9]{8}|$))//g' test.txt
20141101 server contain dump
20141101 server contain nothing    {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdlsddsfd jfkdfk
20141101 server contain dump

-0 позволяет сопоставить регекс через весь файл , и \n(? !([0-9]{8}|$)) является отрицательным обзором, означающим новую строку, за которой не следуют 8 цифр, или конец строки (которая, с -0, будет концом файла).

11
27.01.2020, 20:04

le Program ru Bash:

while read LINE
do
    if [[ $LINE =~ ^[0-9]{8} ]]
    then
        echo -ne "\n${LINE} "
    else
        echo -n "${LINE} "
    fi
done < file.txt

в однополосной форме:

while read L; do if [[ $L =~ ^[0-9]{8} ]]; then echo -ne "\n${L} "; else echo -n "${L} "; fi done < file.txt

решение с сохранением обратной косания ( -R ) и ведущие пробелы (только IFS = после в то время как ):

while IFS= read -r LINE
do
    if [[ $LINE =~ ^[0-9]{8} ]]
    then
        echo
        echo -nE "\n${LINE} "
    else
        echo -nE "${LINE} "
    fi
done < file.txt

однополосная форма:

while IFS= read -r L; do if [[ $L =~ ^[0-9]{8} ]]; then echo; echo -nE "${L} "; else echo -nE "${L} "; fi done < file.text
0
27.01.2020, 20:04

Может быть немного проще с sed

sed -e ':1 ; N ; $!b1' -e 's/\n\+\( *[^0-9]\)/\1/g'
  • first part :1;N;$!b1 собрать все строки в файле, разделенные на \n в 1. длинная строка

  • вторая часть полосы символ новой линии, если она следовала за нецифровым символом с возможные промежутки между ними.

Чтобы избежать ограничения памяти (особенно для больших файлов) можно использовать:

sed -e '1{h;d}' -e '1!{/^[0-9]/!{H;d};/^[0-9]/x;$G}' -e 's/\n\+\( *[^0-9]\)/\1/g'

Или забыть сложные скрипты sedи вспомнить, что год начинается с 2

tr '\n2' ' \n' | sed -e '1!s/^/2/' -e 1{/^$/d} -e $a
5
27.01.2020, 20:04

Одним из способов было бы:

 $ perl -lne 's/^/\n/ if $.>1 && /^\d+/; printf "%s",$_' file
 20141101 server contain dump
 20141101 server contain nothing    {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdlsddsfd jfkdfk 
 20141101 server contain dump

Однако, это также удаляет конечную новую строку. Чтобы добавить его снова, используйте:

$ { perl -lne 's/^/\n/ if $.>1 && /^\d+/; printf "%s",$_' file; echo; } > new

Пояснение

-l удалит скользящие новые строки (а также добавлять по одной к каждому вызову печати, поэтому я использую printf вместо этого. Затем, если текущая строка начинается с цифр (/^\d+/) и текущий номер строки больше единицы ($.>1, это необходимо, чтобы избежать добавления лишней пустой строки в начале), добавьте \n в начало строки. Печать printf распечатывает каждую строку.


Или же вы можете изменить все символы \n на \0, а затем снова изменить те \0, которые стоят прямо перед строкой чисел, на \n:

$ tr '\n' '\0' < file | perl -pe 's/\0\d+ |$/\n$&/g' | tr -d '\0'
20141101 server contain dump
20141101 server contain nothing    {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdlsddsfd jfkdfk 
20141101 server contain dump

Чтобы она совпадала только со строками из 8 чисел, используйте вместо этого:

$ tr '\n' '\0' < file | perl -pe 's/\0\d{8} |$/\n$&/g' | tr -d '\0'
5
27.01.2020, 20:04

Попытка, делающая это использование :

#!/usr/bin/awk -f

{
    # if the current line begins with 8 digits followed by
    # 'nothing' OR the current line doesn't start with 8 digits
    if (/^[0-9]{8}.*nothing/ || !/^[0-9]{8}/) {
        # print current line without newline
        printf "%s", $0
        # feeding a 'state' variable
        weird=1
    }
    else {
        # if last line was treated in the 'if' statement
        if (weird==1) {
            printf "\n%s", $0
            weird=0
        }
        else {
            print # print the current line
        }
    }
}
END{
    print # add a newline when there's no more line to treat
}

Для использования его:

chmod +x script.awk
./script.awk file.txt
3
27.01.2020, 20:04

Другой самый простой путь (чем мой другой ответ) использование и алгоритм terdon :

awk 'NR>1 && /^[0-9]{8}/{printf "%s","\n"$0;next}{printf "%s",$0}END{print}' file
2
27.01.2020, 20:04
sed -e:t -e '$!N;/\n *[0-9]{6}/!s/\n */ /;tt' -eP\;D
1
27.01.2020, 20:04

Теги

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