2011-11-29 42 views
4

我不知道如何用變量執行一個命令並獲取結果。 我有很多.h.c文件,我需要將每個從ISO-8859轉換爲UTF-8。BASH腳本 - 執行帶有變量和存儲結果的命令

所以我提出:

ls | grep "\.[ch]" | xargs myscript.sh 

而且在我的變量$1腳本文件名。現在我需要執行

iconv -f ISO-8859 -t UTF-8 $1 

並存儲這個結果,因爲iconv打印到stdout。

result=`iconv -f ISO-8859 -t UTF-8 $1` 

echo $result 

這似乎是不工作的,因爲它給我一些不匹配,而不是轉換$1

+2

「有些不匹配」?請引用您收到的確切錯誤消息。 –

+0

這不是錯誤。它是更多的文件,然後只有1美元的內容,我不明白這一點。 – designerrr

+0

做任何從你ls |發出的文件grep ..'在文件名中有空格?這會打擊一切。嘗試在'result = ...'中更改爲「$ 1」,但您可能需要想出辦法處理文件名中的空格。請使用適當的示例值編輯您的問題,以獲取1美元和爭奪內容的確切文本。祝你好運。 – shellter

回答

4

如果你需要首先做一些對數據轉換,可以「捕捉」的語法如下輸出:

result="$(iconv -f ISO-8859 -t UTF-8 $1)" 

有一個疑難雜症這裏還有:如果你將要存儲大量含有潛在空白或其他混雜字符的數據時,請務必始終引用變量("$result"而不是$result)以確保它被視爲單個字符串。

+0

這個'$ cmd $ 1> $ 1'不會覆蓋文件,它會首先** **。這是截斷所有源文件的好方法。 – sehe

+0

你說得對。固定。 – Michael

+0

你錯過了我的觀點。所有文件仍然會出來_empty_ – sehe

3

我會做這樣:

while read filename; 
do 
    mv "$filename" "$filename.bck" && \ 
     iconv -f ISO-8859 -t UTF-8 "$filename.bck" > "$filename" 
done < find -iname '*.[hc]' 

這在飛行中產生的備份還負責與空白文件(不換行字符)。

+0

雙引號處理字符串中的換行符(文件名)。 –

+1

@JonathanLeffler:我認爲sehe在談論換行時指的是'while read'。 IIRC,在bash中,你可以'讀取-d $'\ x00''。 – ninjalj

+0

夠公平 - 是的; 'read filename'不會處理換行符。 –

3

這裏,即使處理換行符的解決方案:

find -name '*.[ch]' \ 
    -exec mv '{}' '{}.backup' \; \ 
    -exec iconv -f ISO-8859 -t UTF-8 '{}.backup' -o '{}' \; 

一般情況下,千萬不要解析文件名,如果你要使用的結果。我知道的唯一理智的方法是

  1. 使用殼球,例如, for file in ./*.[ch] ; do echo "$file" ; done。只適用於一個目錄。
  2. 使用找到結合-exec
  3. 使用發現聯合-print0(它打印出的文件名如\ 0分隔的字符串),並使用的輸出與xargs -0和可能的輔助腳本構建COMMANDLINES。雖然這很麻煩。

此外,請確保您使用的相對文件名以./爲前綴。調用mv -from -to是不安全的,但mv ./-from ./-to是,並做你想做的。例如。當globbing時,請使用./*.c而不是*.c

+0

+1非常好的答案 – ninjalj