Подтвердить что ты не робот

'+' (одно или несколько вхождений), не работающих с командой sed

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

    int a = 4;
    if ((a==4) ||   (b==5))

    a++   ;

должен измениться на:

    int a = 4;
    if ( (a==4) || (b==5) )
    a++ ;

Это работает для скобок и пустых строк. Однако он забывает сократить количество пробелов до одного места:

    int a = 4;
    if ( (a==4) ||   (b==5) )
    a++    ;

Вот мой script:

    #!/bin/bash
    # Script to refine code
    #
    filename=read.txt

    sed 's/((/( (/g' $filename > new.txt
    mv new.txt $filename

    sed 's/))/) )/g' $filename > new.txt
    mv new.txt $filename

    sed 's/ +/ /g' $filename > new.txt
    mv new.txt $filename

    sed '/^$/d' $filename > new.txt
    mv new.txt $filename

Кроме того, есть ли способ сделать этот script более кратким, например. удаление или уменьшение количества команд?

4b9b3361

Ответ 1

Если вы используете GNU sed, вам нужно использовать sed -r, который заставляет sed использовать расширенные регулярные выражения, включая желаемое поведение +. См. man sed:

-r, --regexp-extended

       use extended regular expressions in the script.

То же самое, если вы используете OS X sed, но тогда вам нужно использовать sed -E:

-E      Interpret regular expressions as extended (modern) regular expressions
        rather than basic regular regular expressions (BRE's).

Ответ 2

Вы должны выполнить + с помощью \, иначе sed попытается совместить сам символ +.

Чтобы сделать script "умнее", вы можете накапливать все выражения в одном sed:

sed -e 's/((/( (/g' -e 's/))/) )/g' -e 's/ \+/ /g' -e '/^$/d' $filename > new.txt

Некоторые реализации sed поддерживают параметр -i, который позволяет изменять файл на месте.

Ответ 3

Иногда -r и -e не работают. Я использую sed версии 4.2.1, и они вообще не работают для меня.

Быстрый взлом - это использовать вместо этого оператор *. Итак, допустим, мы хотим заменить все избыточные символы пробела одним пространством: Мы хотели бы просто сделать

sed 's/ +/ /'

Но мы можем просто использовать это вместо

sed 's/  */ /'

Ответ 4

Это может сработать для вас:

sed -e '/^$/d' -e ':a' -e 's/\([()]\)\1/\1 \1/g' -e 'ta' -e 's/  */ /g' $filename >new.txt

Ответ 5

на фронте bash;

Сначала я сделал script test.sh

cat test.sh

#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
    echo "Text read from file: $line"
    SRC=`echo $line | awk '{print $1}'`
    DEST=`echo $line | awk '{print $2}'`
    echo "moving $SRC to $DEST"
    mv $SRC $DEST || echo "move $SRC to $DEST failed" && exit 1
done < "$1"

тогда мы создадим файл данных и тестовый файл aaa.txt

cat aaa.txt
<tag1>19</tag1>
<tag2>2</tag2>
<tag3>-12</tag3>
<tag4>37</tag4>
<tag5>-41</tag5>

затем проверьте и покажите результаты.

bash test.sh list.txt 
Text read from file: aaa.txt bbb.txt
moving aaa.txt to bbb.txt