Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 每行vi/vim/sed等首次出现_Regex_Vim_Sed_Awk_Vi - Fatal编程技术网

Regex 每行vi/vim/sed等首次出现

Regex 每行vi/vim/sed等首次出现,regex,vim,sed,awk,vi,Regex,Vim,Sed,Awk,Vi,使用VI替换第一个引用/实例非常简单 :%s/search/replace/args 但是,以下是我的.csv格式/文件的数据集: "192.168.2.1","www.google.com","2009/01/11_10:00"," What a great website" "192.168.2.2/driving/is/fun","-","2009/03/22_00:00","Driving website" "192.168.2.4/boating/is/crazy","-",

使用VI替换第一个引用/实例非常简单

    :%s/search/replace/args
但是,以下是我的.csv格式/文件的数据集:

"192.168.2.1","www.google.com","2009/01/11_10:00"," What a great website"
"192.168.2.2/driving/is/fun","-","2009/03/22_00:00","Driving website"
"192.168.2.4/boating/is/crazy","-","2009/03/22_00:00","Boating Website"
"192.168.2.5","www.cars.com","2009/04/27_00:00","What a good car website"
因此,您会注意到在第一行中,有4列,这是.csv格式的理想行

但是,在第二行中,有4列,但第一列只接受ip地址,仅此而已,因此192.168.2.2/driving/is/fun必须删除或用“,”分隔

在vi中,我能够使用以下内容:

    :/^"\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\//s/\//","/
以下哪项功能:

    :/^"\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\//s/\//","/
  • /^“\d{,3}.\d{,3}.\d{,3}.\d{,3}/-设置一个锚点,用正斜杠/在第一个IP开始搜索。例如,第2行:“192.168.2.2”/

  • /s//“,”/-替换IP地址末尾的/并用.csv分隔符“,”

这在VI/VIM中非常有效,一次只替换一行内容。但是,数据集要大得多,手动使用以下vi搜索和替换非常耗时。我希望编写脚本或找到一个替代解决方案,因为VI/VIM一次只能执行一行,下面是:s/search/replace/g替换行中的每一行/另外更改日期列

显然,我已经尝试了以下方法:

    :/^"\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\//s/\//","/
将整个文件的%添加到替换开始的内部,如下所示:

    :/^"\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\//%s/\//","/
突出显示了我需要修改但出现错误的每个条目:

    E492: Not an editor command: /^"\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\//%s/\//
这相当令人困惑

我最终希望使用sed/perl一次性编写整个文件的编辑脚本

所以

“192.168.2.2/-->”192.168.2.2“

每行第一次出现

任何帮助都将不胜感激


谢谢

在vi/vim中,您可以指定要替换的搜索范围。在这种情况下,您希望替换所有行中的
:%s

:%s/search/replace/g
您还可以指定:

:2,5s/search/replace/g      Replace on lines 2-5
:.,$s/search/replace/g      Replace from current line (.) to last line ($)
:.,+3s/search/replace/g     Replace on the current line (.) and the two next lines (+3)
:g/^asd/s/search/replace/g  Replace on lines starting with 'asd'. 
然后,您可以将其与更简单的模式相结合,在整个文件中进行所需的替换:

:%s/^\("[^/"]*\)[^"]*"/\1"/
这将从CSV中的第一个条目中删除IP地址之后的所有内容

:%s/^\("[^/"]*\)\/\([^"]*\)"/\1","\2/
这将把第一个条目拆分为IP地址和其余的条目,尽管这只适用于IP后面有斜杠的行。
你要做的是找到模式,转到那一行,然后替换。在这种情况下,添加“%”会使命令无效。

您可以使用更简单的模式执行任何操作:

s/^\("[^/"]*\)[^"]*"/\1"/
这是:匹配行首,启动匹配组:匹配
,匹配任意数量的非斜杠字符和非
,关闭匹配组,匹配任意数量的非
”字符,并匹配
。替换为匹配组内容加上一个

上面的模式应该很容易编写脚本

#!/usr/bin/env python
import re
import sys

if len(sys.argv) != 3:
    print("Usage: log_file_cleaner <input_file> <output_file>")
    sys.exit(1)

pat = re.compile(r'^("[^/"]*)[^"]*"')

with open(sys.argv[1]) as in_f, open(sys.argv[2], "w") as out_f:
    for line in in_f:
        line = re.sub(pat, r'\1"', line)
        out_f.write(line)
!/usr/bin/env python
进口稀土
导入系统
如果len(sys.argv)!=3:
打印(“用法:日志文件清理器”)
系统出口(1)
pat=re.compile(r'^(“[^/”]*)[^“]*”)
将open(sys.argv[1])作为in\u f,将open(sys.argv[2],“w”)作为out\u f:
对于in_f中的行:
line=re.sub(pat,r'\1'',第行)
外写(行)
注意:您需要一个最新版本的Python来执行一个
和两个
open()
调用。如果您卡在Cygwin上,您可以使用
语句将上述内容编辑为两个嵌套的
,每个语句执行一个
open()
调用。

在ViM中,尝试:

 :%s/^\("\d\{,3}\.\d\{,3}\.\d\{,3}\.\d\{,3}\)\(\/[^"]\)/\1","\2

也就是说,我使用全局(
%
1的快捷方式,$
即从第一行到最后一行)替换,而不是搜索/替换。我将您的搜索模式移动到替换模式中,并在不同的组中捕获ip地址和路径。然后将它们放回原处,挤压中间的“
”,“

只是一个普通的保护:您可以使用几乎任何字符来界定您的模式。例如,如果你使用管道,你就不必逃避斜杠。史蒂文哈,谢谢你的回复。s/^(“[^/”]*)[^”]*“/\1”/^^^^只突出显示/选择这两者之间的所有内容。因此它突出显示了“192.168.2.1”和“192.168.2.2/driving/is/fun”您了解匹配组是什么,以及它是如何工作的吗?是的,整个模式与“/driving/is/fun”匹配“但比赛小组忽略了它。而且,如果您需要它来拒绝第一个引号后的空白,我可以编辑模式来做到这一点,但您的示例没有表明这是必要的。John Lawrence,感谢您的回复。。“(:%s/search/replace/g)”不起作用。当使用g-global选项时,它也会删除日期中的正斜杠,而不仅仅是IP末尾的正斜杠,它会删除文件中的每个斜杠。如果只使用:%s,则会删除行中的每个正斜杠,删除目录路径和日期等。这是正确的。添加“g”将替换行中的所有匹配项,而不添加“g”将仅替换第一个匹配项。这就是为什么我在你应该使用的正则表达式中省略了“g”。抱歉,如果不清楚,我的答案的前几位还有更多供一般参考。即使使用:%s/\/“,“/对于第一次出现的正斜杠,也会删除IP后没有正斜杠的行项目上的正斜杠,从而删除行中其他地方第一次出现的正斜杠,与日期类似。此外,此数据集由大约1000行组成。。使用设定编号等将线固定。。这和手动操作一样耗时。范围部分也没有太大帮助。John,这个::%s/^([^/“]*)[^”]*“/\1”/非常接近,除了在ip为192.168.2.1/driving/is/fun的线路上,它用“,“但也会删除“驾驶/是/有趣…”。。做得很好。。完美的你能解释一下我遗漏了什么或者你添加了什么,这样我才能理解/了解吗?我在答案中添加了它。如果我能进一步澄清,请告诉我