2009-01-23 59 views
4

在bash中尋找解決方案(將成爲更大腳本的一部分)。在bash中提取所有匹配的子字符串

給出一個包含表單的信息

 
diff -r efb93662e8a7 -r 53784895c0f7 diff.txt 
--- diff.txt Fri Jan 23 14:48:30 2009 +0000 
+++ b/diff.txt Fri Jan 23 14:49:58 2009 +0000 
@@ -1,9 +0,0 @@ 
-diff -r 9741ec300459 myfile.c 
---- myfile.c Thu Aug 21 18:22:17 2008 +0000 
-+++ b/myfile.c Thu Aug 21 18:22:17 2008 +0000 [email protected]@ -1,4 +1,4 @@ 
- int myfunc() 
- { 
--  return 1; 
-+  return 10; 
- } 

我希望提取兩(這裏diff.txt和myfile.c文件,但未來的情況下,將不侷限於這個數)的文件名的字符串變量表單「編輯:文件名1文件名2 ...文件名N」。

爲了澄清,我希望提取多個匹配的文件名到一個字符串。

  • 命令「$(expr」$ editing「:'。* --- [[:space:]] \([[:graph:]] * \)[[:space:]]' )「正確返回最後的文件名,但不是先前的實例。

編輯:需要能夠識別編輯過的文件名(可能包括空格),即出現在「---」之後和「星期五/星期四...」之前的文件名。

感謝您的幫助(以及許多人迄今已回覆)。

回答

3

只使用bash的內置插件解決辦法,沒有外部的程序是:

res="edited: "; var="${var#* --- } --- " 
while test -n "$var";do res="$res ${var%% *}"; var="${var#* --- }";done 
echo "$res" 

它重複上的 「---」 所有出現。 訣竅是先準備字符串,首先從開頭 (至第一個---) 修剪garbarge,然後在末尾附加「---」,以便在後面的while循環中可以有一個更簡單的邏輯。

這是通過使用bash最實用的功能,#和%修剪字符串

0

您可以在設置$編輯之前執行操作 - 那麼您可能仍然有換行符?

然後,也許一些sed將能夠提取文件名。

+0

它可能用grep的組合,sed的處理和awkm這將涉及到文件的創建/刪除,我很希望避免。感謝您的意見。 – anon 2009-01-23 18:57:08

+0

我不得不同意,換行會讓這個更乾淨。 (順便說一句,Bash變量可以包含換行符) – 2009-01-23 18:58:43

1

我建議使用它的外部工具 - 在這裏是用Perl的一種方式:

$(echo "$variable" | perl -e 'print "edited:"; while (<>) { while (/--- (\S+)/g) { print " $1"; } }') 

我敢肯定,它可以更優雅的完成,但現在我不能想辦法這不會採取更實質性的計劃。

1

下面是一個簡單,工作液:

txt=$(cat) 
str="edited: " 

for word in $txt; do 
     if echo $word | grep -qi '^[a-z0-9-_]*\.[a-z]*$'; then 
      str="$str $word" 
     fi 
done 

echo $str 

運行它:

[email protected] ~/Desktop 
$ bash sol.sh 
diff -r efb93662e8a7 -r 53784895c0f7 diff.txt --- diff.txt Fri Jan 23 14:48:30 2 
009 +0000 +++ b/diff.txt Fri Jan 23 14:49:58 2009 +0000 @@ -1,9 +0,0 @@ -diff -r 
9741ec300459 myfile.c ---- myfile.c Thu Aug 21 18:22:17 2008 +0000 -+++ b/myfil 
e.c Thu Aug 21 18:22:17 2008 +0000 [email protected]@ -1,4 +1,4 @@ - int myfunc() - { -- return 
1; -+ return 10; - } 
edited: diff.txt diff.txt myfile.c myfile.c 

編輯:使用grep周圍Dicking一會兒導致下面的腳本,但我開始懷疑純粹的bash是否是適合這項工作的正確工具......看起來好像會有很多角落案例,你會錯過一些文件或者得到錯誤的文件名。

#! /bin/bash 

rawFiles=`cat | grep -ioz ' -* [a-z0-9-_\ ]*\.[a-z]*'` 

for file in $rawFiles; do 
    if ! echo $file | grep -q '^-*$'; then 
     files="$files${file} " 
    fi 
done 

echo "edited: $files" 
+0

非常優雅。唯一不能正常工作的是差異中提到的文件名中有空格,但這種情況很少發生,我懷疑這是一個合理的問題。 – 2009-01-23 19:22:26