我试图在以下输入中使用简单的perl单行程序:
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+
]]^4YY23ZV\6`a8`^9^a
等
我希望我的输出看起来像:
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+F7##########0/1
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+44FC6%%%%&&&&&&&1UP1
]]^4YY23ZV\6`a8`^9^a
等
我想搜索以@
开头的行,并在$1
中存储(分组)该行的其余部分。然后,我找到下一个+
,并在该行的末尾添加$1
。
我已尝试perl -pi -e "s%^@(.*)$\1\n(.*)$\2\n(\+)$\3\n%$1\n$2\n\+$1%mg" file.txt
但我似乎无法在^@(.*)$\1\n
之后匹配任何内容。
当然,那里有一个工作的单行程来实现这一目标。我们欢迎Awk
或Sed
或tr
个单行,但file.txt
的更改必须符合要求,因为file.txt
很大并且写入另一个文件是不受欢迎的。
答案 0 :(得分:3)
不幸的是awk
不提供内联更改,因此可能不是您需要的内容。但如果你这样做,那么下面的工作就可以了 -
awk '/^@/{a=substr($0,2)}/^\+/{printf ("%s%s\n", $0,a);next}1' file > newfile
更新:我已尝试在 sed
中执行您要查找的内容,以便进行in-file
更改。
sed -i '/^@/{h};/^\+/{x;s/\(.\)\(.*\)/+\2/}' file
/^@/{h}
:我们查找以@
符号开头的行,当我们找到它时,我们将整行放在hold space
中。 Sed
有两个缓冲区,pattern space
和hold space
。 Pattern space
是所有行动发生的地方。 hold space
允许我们暂时保留信息,以便我们以后可以对其执行某些操作。 /^\+/{x;...
:当我们找到以+
开头的行时,我们会对其执行x
操作。这意味着,我们从hold space
中提取信息并将其放回pattern space
。一旦我们完成了这个,我们就做了一个简单的替换。 ...s/\(.\)\(.*\)/+\2/
:这意味着我们使用grouping
识别字符。由于我们的部分文本前面有@
,你不想要,我们使用.
来表示任何字符。我们还将该行的其他所有内容放在第二组中。这些组需要进行转义{所以你看到\(\)而不是just()}。在替换部分,我们放入+
和第二组。请记住,第一个捕获的群组中只有@
。我们只想要第二组,因此我们使用\2
(反斜杠和您想要引用的组的数量)来引用它。 awk
:[jaypal:~/Temp] cat file
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+
]]^4YY23ZV\6`a8`^9^a
[jaypal:~/Temp] awk '/^@/{a=substr($0,2)}/^\+/{printf ("%s%s\n", $0,a);next}1' file
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+F7##########0/1
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+44FC6%%%%&&&&&&&1UP1
]]^4YY23ZV\6`a8`^9^a
sed
:您可以使用-i
选项进行更改。以下仅用于演示,以便您可以看到输出。
[jaypal:~/Temp] sed '/^@/{h};/^\+/{x;s/\(.\)\(.*\)/+\2/}' file
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+F7##########0/1
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+44FC6%%%%&&&&&&&1UP1
]]^4YY23ZV\6`a8`^9^a
答案 1 :(得分:2)
道歉。我更仔细地阅读了您的问题,并确定您要逐行处理您的文件。这个单线将实现那个
perl -pe "$dat = $1 if /^\@(.+)/; s/^\+/+$dat/;" infile
答案 2 :(得分:0)
以下程序似乎可以满足您的需求
use strict;
use warnings;
my $str = <<'STR';
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+
]]^4YY23ZV\6`a8`^9^a
STR
$str =~ s/^@(.+?)$(.+?)^\+/\@$1$2+$1/gms;
print $str;
<强>输出强>
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+F7##########0/1
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+44FC6%%%%&&&&&&&1UP1
]]^4YY23ZV\6`a8`^9^a
答案 3 :(得分:0)
这可能对您有用:
sed '/^@/h;/^+/{G;s/\n@//}' file
@F7##########0/1
C4CTA6GCAAC56G67CTCA99C
+F7##########0/1
b[[WZ56W]87X9HBB
@44FC6%%%%&&&&&&&1UP1
GTS4HY2IOMD3FCCA8DFLLLTG
+44FC6%%%%&&&&&&&1UP1
]]^4YY23ZV\6`a8`^9^a