我有一个包含多个路径的文本文件 (.txt),我想过滤它们并只留下路径列表。
该文件将是这样的:
Loremipsumdolorsitametconsecteturadip"/one/path/I_want_to_keep"iscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliqua
Utenimadminimveniamquisnostrudexercitationul"/another/path/I_want_to_keep"lamcolaborisnisiutaliquipexeacommodoconsequat
Duisauteiruredolorinreprehenderitinvoluptatevelitess"/another/path/I_want_to_keep"ecillumdoloreeufugiatnullapariatur
Excepteursintoccaecatcupidatatnonproident"/another/path/I_want_to_keep"suntinculpaquiofficiadeseruntmollitanimidestlaborum
示例中所示的路径有 3 个斜杠 (/),周围有引号 (""),路径的最后部分是由下划线 (_) 分隔的几个单词,周围的文本没有特定的模式。
我正在使用 zsh 5.8 (x86_64-apple-darwin21.0)
答案1
我建议这样:
% grep -o '"/[^"]*"' file
"/one/path/I_want_to_keep"
"/another/path/I_want_to_keep"
"/another/path/I_want_to_keep"
"/another/path/I_want_to_keep"
答案2
和perl
:
perl -lne 'print for grep m{^/.*/.*/}, /"(.*?)"/g' < your-file
将提取带引号的字符串的内容(假设它们不跨越多行)并 grep 以/
至少两个额外/
s` 开头并包含的字符串。
在像这样的输入上
"foo"/x/y/"bar"/"/a/b/c"/"/X/Y"
即foo
、bar
和字符串,其中只有三分之一符合条件/a/b/c
,因此我们只能得到输出。查看如何也没有报告,因为它实际上在引号之外。/X/Y
grep()
/a/b/c
"/x/y/"
/x/y/
既然你提到了zsh
,要对zsh
运算符做类似的事情,你会这样做:
set -o extendedglob
string='"foo"/x/y/"bar"/"/a/b/c"/"/X/Y"'
quoted_strings=()
: ${(S)string//(#b)\"(*)\"/${quoted_strings[$#quoted_strings+1]::=$match[1]}}
print -rC1 ${(M)quoted_strings:#/*/*/*}
在哪里
- 参数扩展标志
S
打开${param//pattern/replacement}
匹配的非贪婪匹配。 (#b)
(为此我们需要extendedglob
)启用b
确认引用(对于匹配的内容(*)
在 中可用$match[1]
)${var::=value}
在扩展时无条件赋值value
给( Bourne shell 的/$var
的变体)。我们在这里使用它来将匹配项附加到数组中。${var-value}
${var:-value}
$quoted_strings
print -rC1
在olumn上打印其参数r
aw1
C
${(M)array:#pattern}
扩展为atch thearray
的元素(是 ksh 的/的变体,它将整个元素作为一个整体删除,而不仅仅是前缀/后缀,并且参数扩展标志将其恢复(保留匹配而不是删除它们)。M
pattern
${var:#pattern}
${var#pattern}
${var%pattern}
M