sed / PATTERN / SUB / $ VAR?
我正在重命名一些文件。
這有效:
ls | while IFS= read -r line; do name=$(echo $line | sed -e 's/\(.*\)/\1.jpg/') && mv $line $name; done
沒關係,但我想讓它更簡潔,比如:
ls | while IFS= read -r line; do name=$(sed -e 's/\(.*\)/\1.jpg/' $line) && mv $line $name; done
後一個範例和各種類似嘗試將文件傳遞給 sed 而不是變數的值。
使用 ˋ
$line
ˋ 和$($line)
兩者都會導致嘗試執行文件。雖然"$line"
,'line'
有和沒有的變化<
,都導致文件被讀入。這裡發生了什麼?變數可以$line
直接與 sed 一起使用嗎?
您可以使用Here String的
<<<
語法:ls | while IFS= read -r line do name=$(sed 's/\(.*\)/\1.jpg/' <<< $line) && mv "$line" "$name" done
請注意,解析的輸出
ls
(也不使用未引用的變數)並不是一個好主意。還有一個工具名稱
rename
(如果目標只是重命名文件):rename -n 's/$/.jpg/' *
刪除
-n
標誌以從預覽更改為實際重命名。
看起來您只是想附加
.jpg
到目前目錄中所有文件名的末尾。如果是這種情況,那麼有更簡單的方法:for f in ./*; do mv -- "$f" "$f.jpg" done
--
確保帶有初始破折號 () 的文件名不會-
被解釋為mv
. 這在這裡不是問題,因為我們還通過在循環中使用確保在開始時$f
始終具有路徑。./``./*
的輸出
ls
是供眼睛閱讀的,通常不適合像您正在做的那樣發送到 while-read-loop 中。是的,在您的第二個範例 (
sed -e 's/\(.*\)/\1.jpg/' $line
) 中,文件的內容將由sed
. 使用 Bash,您可以這樣做sed '...' <<<"$line"
。該<<<"string"
構造是一個 Bash 擴展(至少在ksh
和中也可用zsh
)並且被稱為“here-string”,它會將標準輸入上的字元串傳遞給命令。