我不知道在命令行中是否可以实现这一点,但无论如何,这就是我想做的事情:
我有一个类似的文本文件
- FileName1.txt
http://example.com/AnyName-For-File-1.txt
- FileName2.txt
- FileName3.txt
- FileName4.txt
http://example.com/AnyName-For-File-4.txt
- FileName5.txt
http://example.com/AnyName-For-File-5.txt
正如你所看到的,文本是随机编写的(某种程度上),这意味着某些文件有一个地址,而其中一些文件没有,所以我不能在这些行上应用任何规则,如安排\排序等等,或者我会丢失文件"姓名,地址"布置。
所以,首先我必须移动所有的地址行,一步(这是GUI中的简单部分),我能够使用 Np ++ / TextPad 正则表达式如下: - 查找:\nhttp
- 替换:http
,最终结果如下:
STEP.1: -
- FileName1.txt http://example.com/AnyName-For-File-1.txt
- FileName2.txt
- FileName3.txt
- FileName4.txt http://example.com/AnyName-For-File-4.txt
- FileName5.txt http://example.com/AnyName-For-File-5.txt
现在,最糟糕的部分(至少对我来说)是将匹配模式移动到他们行的开头,完全像这样:
Step.2: -
http://example.com/AnyName-For-File-1.txt- FileName1.txt
- FileName2.txt
- FileName3.txt
http://example.com/AnyName-For-File-4.txt- FileName4.txt
http://example.com/AnyName-For-File-5.txt- FileName5.txt
现在我可以轻松地对它们进行排序,或者我需要的任何东西,没有任何风险。 所以,我的问题是: -
在命令行 CMD 或 Cygwin : -
1-如何查找" \ n http" ,并替换为" HTTP" ?
2-如何将匹配模式(文件地址,从 http 到 .txt )移动到其行的开头?
如果还有其他技术,那么知道它会很棒。
非常感谢你们在这样一个伟大的社区中提供的帮助。我非常感谢你的帮助:)。
答案 0 :(得分:1)
这是一个awk
命令,我认为,它可以做你想要的:
$ awk '/^http/{print $0 last;last="";next} last {print last} {last=$0} END{if (last) print last;}' file2
http://example.com/AnyName-For-File-1.txt- FileName1.txt
- FileName2.txt
- FileName3.txt
http://example.com/AnyName-For-File-4.txt- FileName4.txt
http://example.com/AnyName-For-File-5.txt- FileName5.txt
该脚本有一个变量last
,其中包含上一行的内容。 awk
隐式循环输入文件中的每一行
/^http/{print $0 last;last="";next}
如果当前行以http
开头,则将其与前一行一起打印。将last
设置为空并跳过其余命令并跳至next
行。
last {print last}
如果last
变量不为空,请将其打印出来。只有在没有与last
行一起使用的网址时才会出现这种情况。
{last=$0}
使用当前行更新last
变量。在awk
中,$0
表示整个当前行。
END{if (last) print last;}
在输入结束时,如果last
中仍有一行,则将其打印出来。只有在最后一行是缺少URL的文件名时才会发生这种情况。
sed
只要file
不是太大,这就行了:
$ sed ':a;N;$!b a;s/\nhttp/ http/g' file
- FileName1.txt http://example.com/AnyName-For-File-1.txt
- FileName2.txt
- FileName3.txt
- FileName4.txt http://example.com/AnyName-For-File-4.txt
- FileName5.txt http://example.com/AnyName-For-File-5.txt
这可以通过将整个文件读入sed的模式空间,然后用\nhttp
代替替换http
。
更详细:
:a;N;$!b a
这是一个循环。 :a
是一个标签。 N
读取模式空间中的下一行。 b a
跳转到标签:a
。我们希望继续循环直到文件结束。文件中的最后一行称为$
,而!
表示不。因此,$!b a
表示跳转到标签:a
,除非我们已到达文件的最后一行。
s/\nhttp/ http/g
现在我们在模式空间中拥有整个文件,我们使用\nhttp
替换http
进行全局替换。
这是对上述内容的修改。它将线条读入模式空间,直到它到达以http
开头的行。然后,它从该行前面删除换行符:
$ sed ':a;N;/http/!b a; s/\nhttp/ http/' file
- FileName1.txt http://example.com/AnyName-For-File-1.txt
- FileName2.txt
- FileName3.txt
- FileName4.txt http://example.com/AnyName-For-File-4.txt
- FileName5.txt http://example.com/AnyName-For-File-5.txt
由于这种方法不能立即读取整个文件,因此如果文件很大,则内存更容易。
更详细:
:a;N;/http/!b a
如上所述,这是一个循环。它会将分支返回标签:a
以读取另一行,直到我们获得包含http
的行。
s/\nhttp/ http/
这会用空格替换http
前面的换行符。
答案 1 :(得分:1)
这可能适合你(GNU sed):
sed -r 'N;s/(^-.*)\n(http.*)/\2\1/;P;D' file
一次读取两行,如果模式匹配,则将第2行换成第1行(删除换行符)。那些不匹配的行按原样打印。
答案 2 :(得分:0)
这个简短的Perl程序将按照你的要求进行。
小心备份原始文件,因为它会就地修改文件。
要编辑的文件的路径作为参数传递到命令行,如此
perl edit_file.pl mytext.txt
use strict;
use warnings;
use Tie::File;
tie my @file, 'Tie::File', shift or die $!;
for ( my $i = 1; $i < @file; ) {
if ( $file[$i] =~ m<^http://>i ) {
$file[$i] .= $file[$i-1];
splice @file, $i-1, 1;
next;
}
++$i;
}
<强>结果强>
http://example.com/AnyName-For-File-1.txt- FileName1.txt
- FileName2.txt
- FileName3.txt
http://example.com/AnyName-For-File-4.txt- FileName4.txt
http://example.com/AnyName-For-File-5.txt- FileName5.txt