劇情是這樣的
例如,我們有一個名為 a.txt,b.txt,...z.txt 的檔案串列。目標是將它們命名為 txt.a,txt.b,txt.c...txt.z
輸入:
a.txt
b.txt
c.txt
...
...
z.txt
輸出:
txt.a
txt.b
txt.c
...
...
txt.z
我嘗試了這種單線并獲得了所需的輸出。單線
ls -l *.txt | awk -F " " '{print $9}' | awk -F "." '{str1 = $2; str2 = "."; str3 = $1; str4 = str1 str2 str3; print str4}'
問: 如果 bash 中還有更好的方法來實作此功能,有人可以幫忙嗎?
uj5u.com熱心網友回復:
假設/理解:
- 目標是重命名檔案(問題提到
Goal is to name them as ...但沒有提到mv命令......???) - 所有檔案名都包含一個句點
- 我們想切換檔案名的前/后部分以創建新的檔案名
- 不存在具有新檔案名的檔案(例如,我們目前沒有名為
a.txtand 的檔案txt.a)
一種使用引數擴展的想法,它允許我們消除子行程呼叫的開銷:
for fname in *.txt
do
new_fname="${fname#*.}.${fname%.*}"
echo mv "${fname}" "${new_fname}"
done
對于檔案名a.txt,b.txt而c.txt這會產生:
mv a.txt txt.a
mv b.txt txt.b
mv c.txt txt.c
一旦 OP 對結果感到滿意,echo就可以將其洗掉,腳本應執行實際的mv/rename。
uj5u.com熱心網友回復:
如果基于 Perl 的rename命令可用,請嘗試:
rename 's/^([^.] )\.([^.] )$/$2.$1/' *.txt
重命名規則是 Perl 使用正則運算式的替換運算式:
^匹配(錨定)檔案名的開頭。([^.] )匹配除點以外的任何字符序列。然后匹配的子串可以$1由于周圍的括號被參考。\.匹配一個點。([^.] )再次。現在由 參考$2。$匹配(錨定)檔案名的結尾。$2.$1是替換部分,它在點上交換兩個子串。
請注意,有兩個不同的命令名為rename. 一個是基于 Perl 的,另一個不是。您可以通過查看聯機幫助頁來識別它。如果它包含單詞perlexpr,則它是基于 Perl 的。
uj5u.com熱心網友回復:
for f in [a-z].txt; do mv "$f" "txt.${f%.*}"; done
uj5u.com熱心網友回復:
如果檔案名是最后一列,并且檔案有一個點,則可以使用單個 awk 在一個點上拆分并反向列印 2 個部分。
使用$NF匹配最后一個欄位。
ls -l *.txt | awk '
{
split($NF, a, ".")
print a[2] "." a[1]
}'
如果拆分后應該有2個部分,您可以檢查拆分的結果:
ls -l *.txt | awk '
{
n=split($NF, a, ".")
if (n == 2) print a[2] "." a[1]
}'
或者作為替代使用 sed 和 2 個反向列印的捕獲組,ls -1用于每行列出一個檔案。
ls -1 *.txt | sed -E 's/^([^.] )\.([^.]*)$/\2.\1/'
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/347829.html
上一篇:顯示僅包含檔案的目錄路徑
