Rename

重命名文件會在 tcsh 中產生奇怪的結果

  • August 1, 2016
#!/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"替換tby s, oby a, kby m, ( ebyp被後續出現的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

引用自:https://unix.stackexchange.com/questions/299355