2017-02-21 95 views
0

我試圖找到特定文件中字符串的所有實例的位置;然而,我目前正在運行的代碼只返回第一個實例的位置,然後停在那裏。以下是我目前正在運行:在bash中查找字符串的所有實例的字符位置

str=$(cat temp1.txt) 
tmp="${str%%<C>*}" 

if [ "$tmp" != "$str" ]; then 
echo ${#tmp} 
fi 

該文件是字符串只有一行,我會展示它,但格式問題,需要在不會允許我補充之間的空間適量每個角色。

+1

請輸入樣品和預期產量。 – chepner

+0

我試圖提交示例輸入,但問題的格式不允許我在字符之間應用適量的間距。它基本上是多行包含的一行,每行之間有不同數量的空格。我只需要每個事件的位置。 – Zach

回答

1

我不知道的你的要求很多細節,但是這是一個awk一行代碼:

awk -vRS='<C>' '{printf("%u:",a+=length($0));a+=length(RS)}END{print ""}' temp1.txt 

讓我們輸入的實際行測試:

$ awk -vRS='<C>' \ 
    '{printf("%u:",a+=length($0));a+=length(RS)}END{print ""}' \ 
    <<<" <C>  <C> " 
4:14:20: 

這意味着:第一個<C>位於第4個字節,第二個<C>位於第14個字節(包括第一個<C>的三個字節),整行長度爲20個字節(包括最終換行符)。

這是你想要的嗎?

說明

我們設置(-v)記錄分隔符(RS)爲<C>。然後我們保留一個變量a到目前爲止處理的所有字節數。對於每一個「行」(即<C>-分隔的子串),我們將當前行的長度加到a,printf它以合適的格式"%u:",並將a增加a,結束當前行的分隔符的長度。由於到目前爲止還沒有印刷包含換行符,因此在END我們print一個空字符串,這是一個輸出最終換行符的習慣用法。

+0

我跑這個和我的電腦似乎是拒絕-v記錄分隔符:「awk:無效的-v選項」 – Zach

+0

無視,有一個錯字,它的工作!非常感謝! – Zach

0

看看基本上同樣的問題問here

特別是您的問題可能會因多個實例而得到解答,這要歸功於用戶 JRFerguson使用perl的響應。

編輯:我發現另一個解決方案,可能只是做竅門here。 (主要問題和回覆帖子被發現here

我將shell從ksh更改爲bash,將搜索到的字符串更改爲包含多個<C>以更好地演示問題的答案,並將其命名爲「tester」:

#!/bin/bash 
printf '%s\n' '<C>abc<C>xyz<C>123456<C>zzz<C>' | awk -v s="$1" ' 
{  d = "" 
     for(i = 1; x = index(substr($0, i), s); i = i + x + length(s) - 1) { 
       printf("%s%d", d, i + x - 1) 
       d = ":" 
     } 
     print "" 
}' 

這是我如何運行它:

$ tester '<C>' 
1:7:13:22:28 

我還沒有想出的代碼了(我想知道爲什麼它的工作原理),但它似乎工作!這將很好地得到一個解釋和一個優雅的方式來餵你的字符串到這個腳本。乾杯。

+0

我實際上使用這個問題來寫我的第一次嘗試這個代碼。它只返回我正在搜索的字符串的第一個匹配項。 – Zach

相關問題