Rename
重命名文件會在 tcsh 中產生奇怪的結果
#!/usr/bin/tcsh setenv LC_ALL de_DE rm /home/users0/me/master/me/LookupScripts/Sampa/* foreach f ( /home/users0/me/master/me/LookupScripts/Tokenized/*.txt ) set g = "`basename $f .txt`" set h = "`echo $g | tr "tokenized" "sampa"`" cat $f | ./a4.lookup > Sampa/$h.txt end
在
/home/users0/me/master/me/LookupScripts/Tokenized/
我有一些.txt
名為randomnumber_tokenized.txt
. 我想在它們上執行一個腳本,我想將腳本的輸出放到文件夾中Sampa/
,我想保留randombumber_
文件名,但我想將tokenized
部分重命名為sampa
,以便新文件看起來像randomnumber_sampa.txt
.奇怪的是,最終文件沒有被呼叫
randomnumber_sampa.txt
,但是randomnumber_samaaaaaa.txt
我懷疑這要麼是 tcsh 的問題,要麼是因為
setenv
命令。我究竟做錯了什麼?
你的直接問題是它
tr
沒有做你認為它做的事情。tr
執行字元替換,而不是字元串替換。該命令tr "tokenized" "sampa"
替換t
bys
,o
bya
,k
bym
, (e
byp
被後續出現的e
), and ,n
,i
和by替換。z``e``d``a
要執行字元串替換,您可以使用 sed。但這有點不方便,而且很難做到正確。對於簡單的字元串操作,使用 shell 的字元串操作結構而不是外部工具。
Tcsh 缺少字元串操作結構。但是 (t)csh 在過去 20 年左右的時間裡一直不是第 1 層命令行 shell,而且從來沒有對腳本編寫好過。只是不要編寫 csh 腳本。
還:
- 切勿設置為(或其同義詞)
LC_ALL
以外的任何內容。覆蓋所有類別,這可能會導致問題。要為所有類別設置預設值,請使用. 但在腳本中,通常是您需要的,除了(字元集)和(使用者消息)。C``POSIX``LC_ALL``LANG``C``LC_CTYPE``LC_MESSAGES
- sh 中的字元串操作是通過參數擴展完成的。
- 普通的 sh 沒有字元串替換結構,但 bash 有。
- 始終在變數替換周圍使用雙引號
#!/bin/bash export LC_ALL=C for f in /home/users0/me/master/me/LookupScripts/Tokenized/*.txt; do g="${f##*/}" h="${g//tokenized/sampa}" ./a4.lookup <"$f" >"Sampa/$h.txt" end