2016-08-02 42 views
0

有一個文件夾結構如下圖所示./all_files搜索使用參考文件和打印匹配線

-rwxrwxrwx reference_file.txt 
drwxrwxrwx file1.txt 
drwxrwxrwx file2.txt 
drwxrwxrwx file3.txt 

reference_file.txt具有文件名作爲在FILE1.TXT和file2下面所示

$cat reference_file.txt 
file1.txt 
file2.txt 

數據.txt如下所示:

$cat file1.txt 
step_1 
step_2 
step_3 

現在,我必須採取特定的步驟說step2從每個文件

注1:文件名必須顯示在reference_file.txt

注2:總是2:第二步是不是號線

注意3:搜索應遞歸執行。

我用下面的腳本:

#!/bin/sh 

for i in cat reference_file.txt; 

do 
    find . -type f -name $i | grep -v 'FS*' | xargs grep -F 'step_2' 
done<reference_file.txt 

使用上面的代碼後,我沒有輸出。

# bash -x script.sh 
+ for i in cat reference_file.txt 
+ find . -type f -name **cat** 
+ xargs grep -F 'step_2' 
+ for i in cat **reference_file.txt** 
+ find . -type f -name reference_file.txt 
+ xargs grep -F 'step_2' 

增加了新的要求:

目標= step_XX_2其中XX可以是任何東西,應該跳過搜索..所以這個願望輸出中會.. step_ab_2 step_cd_2 step_ef_2

+0

你爲什麼要閱讀'reference_file.txt'兩次?您可以將文件「貓」化,然後將其重定向到循環的標準輸入中 - 看起來您並不使用它。你想用兩個星號來達到什麼目的? – cdarke

+0

你能顯示所需的輸出嗎? – cdarke

+1

您的for循環遍歷兩個元素'cat'和'reference_file.txt'。使用'while'而不是'for'。 – choroba

回答

1

我認爲這是你正在努力實現的。請讓我知道:

編輯:我以前的版本沒有遞歸搜索。 進一步修改:請注意,使用find的進程替換意味着此腳本必須在bash下運行,而不是sh

進一步編輯更改規格:注意更改爲target-E選項到grep而不是-F

#!/bin/bash 

target='step_.*?_?2' 

while read -r name 
do 
    # EDIT: exclude certain directories 
    if [[ $name == "old1" || $name == "old2" ]] 
    then 
     # do the next iteration of the loop 
     continue  
    fi 

    while read -r fname 
    do 
     if [[ $fname != FS* ]] 
     then 
      # Display the filename (grep -H is not in POSIX) 
      if out=$(grep -E "$target" "$fname") 
      then 
       echo "$fname: $out" 
      fi 
     fi 
    done < <(find . -type f -name "$name") 

done < reference_file.txt 

請注意,您的跟蹤(bash -x)使用bash的,但你的#!行使用sh。他們是不同的 - 你應該與你使用的shell一致。

因此,我放棄了xargs,它讀取字符串標準輸入並使用字符串作爲參數執行程序。由於我們已經有了grep的參數字符串,我們並不需要它。您的grep -v 'FS*'可能不符合您的期望。正則表達式FS*的意思是「F跟零個或多個S」。與shell模式匹配不同(globbing)。在我的解決方案中,我使用了FS*,因爲我使用的是shell,而不是grep

+0

謝謝,是否有可能顯示文件名以及...'file1.txt:step_2'' file2.txt:step_2',以便我可以檢查文件是否也存在reference_file.txt – user180946

+0

好!因爲'for $(find ...)'中的fname似乎沒有看到[如何循環查找由find返回的文件名?](http://stackoverflow.com/a/9612232/1983854)非常安全。 – fedorqui

+0

@fedorqui可以請建議代碼的變化,它只使用while循環請。還顯示包括文件名稱和結果 – user180946

0

我相信這個問題你需要的是複製的this

#!/bin/sh 

for i in `cat reference_file.txt` 
    do find . -type f -name $i | grep -v 'FS*' | xargs grep -F 'step_2' 
done 

請參閱反引號,並且不要兩次讀取文件reference_file.txt。

+1

'$(cat reference_file.txt)'語法是首選,反引號被認爲已被棄用。更好的是,你很少需要'貓'。 – cdarke

+0

@cdarke a'我在$(貓...)'是不安全的。 [爲什麼你不用「for」來讀行(http://mywiki.wooledge.org/DontReadLinesWithFor)。最好說'while IFS = read -r var1 var2 ...;做...完成 fedorqui

+1

@fedorqui:沒有任何爭論,看到我的帖子。腳本中很少需要「貓」。我的評論的重點是反引號。 – cdarke