為所有 bash 文件添加 .sh 副檔名
我有一個包含多個文件的目錄,其中一些文件是 bash 腳本,但它們的名稱不包含 .sh 副檔名。我知道我需要使用 file 命令來了解帶有 -type 選項的文件類型,我也知道我可以使用 xargs 重定向輸出,因此我可以使用它們的原始名稱 + .sh 副檔名重命名文件。問題是我不知道如何將所有命令連接在一起,以及如何查找只有 bash ASCII 文本執行檔的文件類型。知道如何用一個簡單的命令來做到這一點嗎?
雖然這不能完成你的作業,但不需要
find
作為grep
kann 遞歸搜尋文件的目錄-r
(甚至在文件名通過 globbing 傳遞時也不需要)grep -lIw '^#!.*bash' dir/!(*.sh) | xargs -I_ mv _ _.sh
grep
-r
dir將搜尋所有子目錄中的所有文件(此處未使用)grep
-l
類似於-H
列印每個匹配的文件名,但抑制正常輸出。此外,它在第一次匹配後停止,類似於-q
或-m1
grep
-I
排除二進製文件,只處理文本文件grep
-w
bash將僅匹配整個單詞(不會匹配bash ed)正則表達式
^
#! 僅匹配行首(不匹配 # #!)正則表達式
.
匹配任何字節*
任何出現=.*
任何字元串路徑名擴展(萬用字元)
*.sh
匹配模式 file.sh擴展萬用字元
!(pattern)
匹配除模式之外的任何內容ls
dir/!(*.sh)
列出 dir 中的所有文件,不包括dir/file.sh文件xargs
-I
模式將在此範例中使用的每個位置模式上插入參數:_
mv _ _ .sh mv file1 file1.sh mv file2 file2.sh
如果您設置了任何標準的 shebang 線,它看起來
file
(至少版本 5.39)應該能夠檢測到它們:$ echo '#!/usr/bin/env bash' > 1 $ echo '#!/bin/bash' > 2 $ echo '#!/usr/bin/bash' > 3 $ file * 1: Bourne-Again shell script, ASCII text executable 2: Bourne-Again shell script, ASCII text executable 3: Bourne-Again shell script, ASCII text executable
所以我們應該能夠做到這一點:
for path in ./* do if [[ "$(file "$path")" = "${path}: Bourne-Again shell script, ASCII text executable" ]] then mv "$path" "${path}.bash" fi done
這適用於上述範例文件(並且應該適用於不尋常的文件名,包括那些包含空格字元、以連字元開頭或以換行符結尾的文件名):
$ ls 1.bash 2.bash 3.bash
如果您的文件沒有 shebang 行,這可能不起作用(這對於由其他腳本或 shebang 行錯誤的文件是合理的(例如
#!/bin/sh
)。(我使用了“.bash”,因為它比“.sh”更明確。)