在两个双引号之间使用sed get子字符串


14

我有一个档案

xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
"/home/path/to/file1": Permission denied (13) rsync:
"/home/path/to/file2": Permission denied (13) rsync:
"/home/path/to/file3": Permission denied (13)

现在,我只想提取文件路径并将其存储到另一个文件。输出文件如下:

/home/path/to/file 
/home/path/to/file1 
/home/path/to/file2
/home/path/to/file3

使用sed或awk我该怎么做?

我已经尝试过,sed -n '/"/,/"/p' myfile但是没有用。


3
对于那些投票要求关闭的人-这怎么可能成为话题?这是关于shell编程的!!这是编程的问题,它是堆栈溢出的话题!
乔纳森·莱夫勒

2
欢迎使用堆栈溢出。如您所见,我们有时会遇到一些问题,即触发手指发痒的人会完美地关闭好问题(例如此问题),而导致关闭的原因不好。它并不会经常发生(或者,我无法经常看到这个问题),但是确实会发生。不要忘了不久阅读FAQ
乔纳森·勒夫勒

Answers:


17

您可以将rsync命令的stderr管道传输到awk脚本:

awk -F '"' '{print $2}' 

或这样的剪切命令:

cut -d'"' -f2

2
或更短一点:cut -d\" -f2

@AndersJohansson:谢谢,我还添加了cut命令来回答。
anubhava 2012年

我认为这行不通..您可以看到文件路径的字段号不是固定的$ 2或f2 ..谢谢!

实际上,rsync总是始终首先在stderr 之间""之上写入文件路径。
anubhava

1
@ Jam88:实际上,由于anubbhava编写它的方式,它可以工作。字段分隔符设置为双引号。这意味着直到第一个双引号(可能是一个空字符串)的所有内容都是$1; 第一和第二双引号之间的一切是$2; 第二个双引号之后的所有内容都在$3$4,...)中。文件名(显然)始终在前两个双引号之间,因此此解决方案应该可以工作(并且在我测试时可以做到)。
乔纳森·莱夫勒

6

使用sed

sed 's/^[^"]*"\([^"]*\)".*/\1/'

查找以下内容:行首,一系列非引号,双引号,捕获一系列非引号,双引号和行中的其他任何内容,然后将其替换为捕获的材料。

$ sed 's/^[^"]*"\([^"]*\)".*/\1/' <<'EOF'
> xyz... rsync: "/home/path/to/file": Permission denied (13) rsync:
> "/home/path/to/file1": Permission denied (13) rsync:
> "/home/path/to/file2": Permission denied (13) rsync:
> "/home/path/to/file3": Permission denied (13)
> EOF
/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3
$

在带有GNU的RHEL 5 Linux上进行测试sed,但只能使用在的第七版UNIX™版本中可以使用的功能sed

顺便说一句,使用两个替代命令来完成此操作稍微简单一些。将直到第一个双引号之前的所有内容都更改为一个空字符串(这是一个零个或多个非引号,后跟一个双引号的序列);将现在第一个双引号之后的所有内容都更改为:

sed 's/^[^"]*"//; s/".*//'

顺便说一句,您尝试的命令(`sed -n'/“ /,/” / p')从包含双引号的一行打印到包含双引号的下一行,而无需编辑所有行。这就是为什么它似乎对您不起作用的原因-它满足了您的要求,但您要执行的操作并非您要执行的操作。

在效率方面,性能不可能有可测量的差异。就维护的简便性而言,我怀疑后者对脑细胞的负担较少。


1

如果您的grep支持Perl-regexp 版本:

grep -oP '(?<=")/home/.*?(?=")' file >> anotherfile

结果:

/home/path/to/file
/home/path/to/file1
/home/path/to/file2
/home/path/to/file3

如果您愿意,也可以使此限制不那么严格,以匹配双打之间的任何内容:

grep -oP '(?<=")[^"]*' file >> anotherfile

您是否需要设置.*非贪婪性,.*?以防行中稍后出现多余的双引号?还是用[^"]*代替.*
乔纳森·勒夫勒

-1

使用>>运算符将所有输出保存到文件。

喜欢

grep -r "pattern" * >> file.txt

因此,只需通过添加sed来针对您的特定场景进行更改

>> filename

到命令


grep -r不通过(在参数中列出的目录中递归搜索*)。目前尚不清楚您打算使用哪种模式,但是grep会占用整条线。练习的目的是从部分线路中收集信息。如果您使用的是GNU grep,则可以通过多种方法(-o); 这些是非标准的(除非GNU定义了事实上的标准)。与使用PCRE正则表达式类似;这些是另一个GNU扩展。如果您有GNU grep并且没有计划在grep默认情况下不可用的GNU平台上工作的计划,那么它们很好。
乔纳森·勒夫勒

抱歉,我错过了,我想他通常想知道将输出放入文件中该怎么做,而grep只是一个例子。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.