'+' (одно или несколько вхождений), не работающих с командой 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 более кратким, например. удаление или уменьшение количества команд?
Ответы
Ответ 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