Shell-Script
如何從一堆文本中過濾路徑列表?
我有一個包含多個路徑的文本文件 (.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)
我提出這個:
% 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"
與
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
ack-references(對於匹配的(*)
內容$match[1]
)${var::=value}
在擴展時無條件地賦值value
(Bourne shell的/的一種變體)。我們在這裡使用它來將匹配項附加到數組中。$var``${var-value}``${var:-value}``$quoted_strings
print -rC1
在olumn上列印其參數r
aw1
C
${(M)array:#pattern}
擴展為匹配的元素(是array
ksh的/的變體,它將整個元素作為一個整體刪除,而不僅僅是前綴 / 後綴,並且參數擴展標誌將其還原(保留匹配項而不是刪除它們)。M``pattern``${var:#pattern}``${var#pattern}``${var%pattern}``M