bash “+”(出现一次或多次)不适用于“sed”命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12101440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
'+' (one or more occurrences) not working with 'sed' command
提问by Siddhartha
I'm trying to refine my code by getting rid of unnecessary white spaces, empty lines, and having parentheses balanced with a space in between them, so:
我试图通过删除不必要的空格、空行以及括号与它们之间的空格来平衡我的代码,所以:
int a = 4;
if ((a==4) || (b==5))
a++ ;
should change to:
应该改为:
int a = 4;
if ( (a==4) || (b==5) )
a++ ;
It does work for the brackets and empty lines. However, it forgets to reduce the multiple spaces to one space:
它确实适用于括号和空行。但是,它忘记将多个空格减少到一个空格:
int a = 4;
if ( (a==4) || (b==5) )
a++ ;
Here is my 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
Also, is there a way to make this script more concise, e.g. removing or reducing the number of commands?
另外,有没有办法使这个脚本更简洁,例如删除或减少命令的数量?
回答by Sicco
If you are using GNU sedthen you need to use sed -r
which forces sed
to use extended regular expressions, including the wanted behavior of +
. See man sed
:
如果您使用的是GNU sed,那么您需要使用sed -r
哪些强制sed
来使用扩展的正则表达式,包括+
. 见man sed
:
-r, --regexp-extended
use extended regular expressions in the script.
The same holds if you are using OS X sed, but then you need to use sed -E
:
如果您使用的是OS X sed 也是如此,但是您需要使用sed -E
:
-E Interpret regular expressions as extended (modern) regular expressions
rather than basic regular regular expressions (BRE's).
回答by choroba
You have to preceed +
with a \
, otherwise sed
tries to match the character +
itself.
你必须preceed+
用\
,否则sed
会尝试将匹配字符+
本身。
To make the script "smarter", you can accumulate all the expressions in one sed:
为了使脚本“更智能”,您可以在一个 sed 中累积所有表达式:
sed -e 's/((/( (/g' -e 's/))/) )/g' -e 's/ \+/ /g' -e '/^$/d' $filename > new.txt
Some implementations of sed
even support the -i
option that enables changing the file in place.
的某些实现sed
甚至支持-i
启用就地更改文件的选项。
回答by statueofmike
Sometimes, -r and -e won't work. I'm using sed version 4.2.1 and they aren't working for me at all.
有时, -r 和 -e 不起作用。我正在使用 sed 4.2.1 版,但它们根本不适合我。
A quick hack is to use the * operator instead. So let's say we want to replace all redundant space characters with a single space: We'd like to do:
一个快速的技巧是改用 * 运算符。所以假设我们想用一个空格替换所有多余的空格字符:我们想做:
sed 's/ +/ /'
But we can use this instead:
但是我们可以用它来代替:
sed 's/ */ /'
(note the double-space)
(注意双空格)
回答by dosentmatter
May not be the cleanest solution. But if you want to avoid -E
and -r
to remain compatible with both versions of sed, you can do a repeat character cc*
- that's 1 c
then 0 or more c
's ==
1 or more c
's.
可能不是最干净的解决方案。但是如果你想避免-E
并-r
保持与两个版本的 sed 兼容,你可以做一个重复字符cc*
- 即 1c
然后 0 或更多c
的==
1 或更多c
的。
Or just use the BRE syntax, as suggested by @cdarke, to match a specific number or patternsc\{1,\}
. The second number after the comma is excluded to mean 1 or more.
或者只是使用@cdarke建议的 BRE 语法来匹配特定的数字或模式c\{1,\}
。排除逗号后的第二个数字表示 1 或更多。
回答by Calvin Taylor
on the bash front;
在 bash 方面;
First I made a script test.sh
首先我做了一个脚本 test.sh
cat test.sh
猫测试.sh
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
echo "Text read from file: $line"
SRC=`echo $line | awk '{print }'`
DEST=`echo $line | awk '{print }'`
echo "moving $SRC to $DEST"
mv $SRC $DEST || echo "move $SRC to $DEST failed" && exit 1
done < ""
then we make a data file and a test file aaa.txt
然后我们制作一个数据文件和一个测试文件aaa.txt
cat aaa.txt
<tag1>19</tag1>
<tag2>2</tag2>
<tag3>-12</tag3>
<tag4>37</tag4>
<tag5>-41</tag5>
then test and show results.
然后测试并显示结果。
bash test.sh list.txt
Text read from file: aaa.txt bbb.txt
moving aaa.txt to bbb.txt
回答by potong
This might work for you:
这可能对你有用:
sed -e '/^$/d' -e ':a' -e 's/\([()]\)/ /g' -e 'ta' -e 's/ */ /g' $filename >new.txt