2014-07-13 84 views
0

我試圖遍歷目錄中的每個文件和文件夾,並將文件名的一部分提取到一個變量,但我不能讓sed正常工作。我要麼獲得所有的文件名,要麼沒有。如何在OS X上使用sed提取子字符串?

這個版本的腳本應該捕捉整個文件名:

#!/bin/bash 
for f in * 
do 
    substring=`echo $f | sed -E -n 's/(.*)/\1/'` 
    echo "sub: $substring" 
done 

而是我得到什麼:

sub: 
sub: 
sub: 
sub: 
... 

這個版本應該給我只是第一個字符的文件名:

#!/bin/bash 
for f in * 
do 
    substring=`echo $f | sed -E 's/^([a-zA-Z])/\1/'` 
    echo "sub: $substring" 
done 

而是我得到整個文件名:

sub: Adlm 
sub: Applications 
sub: Applications (Parallels) 
sub: Desktop 
... 

我試過它無數次的迭代,它基本上可以歸結爲是,如果我使用-n我得到什麼,如果我不我得到整個文件名是什麼。

有人可以告訴我如何得到第一個字符嗎?

或者,我的總體目標是能夠提取一個子字符串並將其存儲到一個變量中,如果有人有更好的方法來處理它,那也是值得讚賞的。

在此先感謝。

+0

我認爲你想'grep -o'而不是sed – FDinoff

+1

你不應該使用陳舊過時的backtics。像這樣使用括號'var = $(code)' – Jotne

+0

爲什麼我的問題得到了低估?要求我可以避免將來的錯誤。 – cutmancometh

回答

1

這個版本的腳本應該捕捉整個文件名:

SED -E-N的/(。*)/ \ 1 /」

而是我什麼也沒得到。

您使用-n如此自然,它不會產生任何東西。也許你應該刪除-n或添加p

sed -E -n 's/(.*)/\1/p' 

這個版本應該給我只是第一個字符的文件名:

的sed -E「s/^([A-ZA-Z ])/ \ 1 /」

而是我得到整個文件名,

你沒有代表繫上任何東西。也許你想要的是

sed -E 's/^([a-zA-Z]).*/\1/' 

此外,我建議你報價參數得好:

substring=`echo "$f" | sed ...'` 

最後的簡單的方法是,如果你使用bash由kojiro的建議使用串擴張。

+0

謝謝。問題是我在捕獲組之後錯過了*。其他人也指出了這一點,但我給了你對號,因爲你有最完整的答案。 – cutmancometh

1

你忘了在SED捕獲組後添加.*

$ for i in *; do substring=`echo $i | sed -E 's/^(.).*$/\1/'`; echo "sub: $substring"; done 

這是更好地使用.,而不是[a-zA-Z],因爲如果第一個字符的任何特殊字符啓動它可能會失敗。

+0

這解決了它。謝謝。 – cutmancometh

+0

你不應該使用陳舊過時的背影。像這樣使用括號'var = $(code)' – Jotne

+0

@Jotne是的,我知道。有人說,OSX不會支持'$()' –

4

如果要修改shell參數,可能需要使用參數擴展。

for f in *; do 
    # This version should expand to the whole parameter 
    echo "$f" 
    # This version should expand to the first character in the filename 
    echo "${f::1}" 
done 

參數擴展不如sed那樣強大,但它們內置於所述殼體(沒有啓動一個單獨的處理或子外殼必要)並有擴展爲:

  1. 子串(如上)
  2. 更換而代字符
  3. 改變字符串的情況下(bash的4+)

以及更多。

+0

謝謝,這是很好的知道。但至於我目前的問題,我需要知道如何使用正則表達式來獲取文件名的特定位。在這種情況下,我只是使用了文件名的第一個字母,因爲它是一個非常簡單的正則表達式,我想將問題歸結爲最簡單的形式。但下一次我需要索引的子串,我會用這個。 – cutmancometh

1

我更喜歡awk sed。這對我來說似乎更容易理解。

#!/bin/bash 
#set -x 
for f in * 
do 
    substring=`echo $f | awk '{print substr($1,1,1)}'` 
    echo "sub: $substring" 
done 
+0

你不應該使用陳舊過時的背影。像這樣使用括號'var = $(code)' – Jotne