使用bash,从下面的F90代码中,我尝试删除最后一个"&"如果下一行以" AA"开头(注意AA之前的空白)。
F = 2 * 3 * a * b * 7&
& * 3 * b * c
AA = ...
应该成为
perl -0pe 's/\&\n\s*AA/\nAA/g' $MYFILE
有Bash - Remove the last character of the line this before?的建议。 基于此,我尝试了
sed -i 's/\&\n\s*AA/\nAA/g' $MYFILE
以及
\s*
不会产生任何错误,但也不会改变任何错误。我也试过没有<UserControl ...>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock><Run Text="Some text"/></TextBlock>
<ScrollViewer
Grid.Row="1"
CanContentScroll="True"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
MinWidth="{Binding ActualWidth,
BindsDirectlyToSource=True,
ElementName=userControl, Mode=OneWay}">
。
答案 0 :(得分:3)
使用GNU sed:
$ sed -z 's/&\n AA/\n AA/g' file
F = 2 * 3 * a * b * 7&
& * 3 * b * c
AA = ...
为了简化此命令,我们使用-z
选项一次读入整个文件。 (从技术上讲,-z
读取NUL分隔的输入。由于没有有效的Fortran文件包含NUL,因此具有读取整个文件的效果。)
s/&\n AA/\n AA/g
执行我们想要的替换。文件包含&
后跟换行符后跟空格后跟AA
的任何地方,此替换会移除&
。
如果文件太大而无法放入内存中,那么立即读取整个文件并不是一个好方法。对于Fortran文件,这不应该是一个问题。
对于非GNU sed(BSD,OSX),我们需要添加代码来替换-z
标志:
sed 'H;1h;$!d;x; s/&\n AA/\n AA/g' file
$ awk '{if (/^ AA/) sub(/[&]$/, "", last); if (NR>1) print last; last=$0} END{print last}' file
F = 2 * 3 * a * b * 7&
& * 3 * b * c
AA = ...
工作原理:
此脚本使用一个变量last
,其中包含上一行的内容。如果当前行以AA
开头,则我们会从&
中删除最终last
(如果有)。更详细:
if (/^ AA/) sub(/&$/, "", last)
如果当前行以AA
开头,则从上一行中删除最后的&
。
if (NR>1) print last
如果我们不在第一行,则打印上一行。
last=$0
将当前行保存为last
。
END{print last}
在我们到达文件末尾后,请打印last
。
使用GNU sed:
sed -zi.bak 's/&\n AA/\n AA/g' file
使用其他sed:
sed -i.bak 'H;1h;$!d;x; s/&\n AA/\n AA/g' file
最近的GNU awk:
awk -i inplace '{if (/^ AA/) sub(/&$/, "", last); if (NR>1) print last; last=$0} END{print last}' file
使用较旧的awk或非GNU awk:
awk '{if (/^ AA/) sub(/&$/, "", last); if (NR>1) print last; last=$0} END{print last}' file >file.tmp && mv file.tmp file
答案 1 :(得分:3)
如果将整个文件加载到内存中会变得非常容易(因为-0777
原因)。
perl -0777pe's/&(?=\n[^\S\n]*AA)//g'
在不将整个文件加载到内存中的情况下使用滑动窗口完成。
perl -ne'$p=~s/&(?=\n)// if /^\s*AA/; print $p; $p=$_; END { print $p }'
或
perl -pe'print $s if !/\s*AA/; $s = s/&\n// ? $& : ""; END { print $s }'
所有三个在AA
之前接受任意数量的空格和制表符。
用法:
perl ... file.in >file.out # From a file
perl ... <file.in >file.out # From STDIN
perl -i~ ... file # "In-place", with backup
perl -i ... file # "In-place", without backup
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed -r 'N;s/&([^&]*\n\s*AA)/\1/;P;D' file
在模式空间(PS)中读取两行,并使用模式匹配从第一行删除&
,如果第二行开始(少于空白)AA
。
N.B。这适用于第二行也包含&
等等......