Bash

為所有 bash 文件添加 .sh 副檔名

  • February 16, 2021

我有一個包含多個文件的目錄,其中一些文件是 bash 腳本,但它們的名稱不包含 .sh 副檔名。我知道我需要使用 file 命令來了解帶有 -type 選項的文件類型,我也知道我可以使用 xargs 重定向輸出,因此我可以使用它們的原始名稱 + .sh 副檔名重命名文件。問題是我不知道如何將所有命令連接在一起,以及如何查找只有 bash ASCII 文本執行檔的文件類型。知道如何用一個簡單的命令來做到這一點嗎?

雖然這不能完成你的作業,但不需要find作為grepkann 遞歸搜尋文件的目錄-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)匹配除模式之外的任何內容

lsdir/!(*.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”更明確。)

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