Bash

以遞歸方式將文件路徑添加到文件的腳本

  • September 16, 2011

我是一名評分員,送出給我的文件最終會放在一個以學生姓名命名的文件夾中,該文件夾本身位於我的 linux 共享的特定文件夾中。

目前,我瀏覽每個源文件並在每個文件的頂部手動添加註釋,這樣當我列印出來時,我就可以知道哪些文件屬於哪些學生。

我想要做的是遞歸地瀏覽家庭作業文件夾,當我下拉到每個學生文件夾時,使用學生目錄名稱在該文件夾中的每個文件的頂部添加評論,以了解要放入評論的內容。

就在文件頂部添加評論而言,這似乎相似,但我不確定如何在放入每個學生文件夾時動態創建評論。

最近的更新

仍然無法正常工作,但這是我所做的更改,因此您不必尋找它們。

我做了一些改變:

  • printf 語句中的單引號現在是雙引號,因為'inisn't提前終止了它。
  • 更改-writable-perm 664可寫會引發錯誤,並且我嘗試更改的所有文件在上傳時都設置為 644。如果您知道比這更好的方法,請告訴我。
  • 如果我正確理解 exec 現在 $1 未聲明(echo $1在 exec 參數中添加證實了這一點),所以我在 exec 參數的末尾添加_filepath={}並刪除了。{}
  • 初始化_dirname__filepath
  • 在使用正則表達式隔離目錄名稱的兩行中,雙引號沒有關閉。現在 _dirname 之後成功地保存了目錄的名稱
  • 現在呼叫 ed_filepath

我很確定它不起作用的原因是因為呼叫 ed 的行中的單引號正在關閉 exec 參數。

目前程式碼:

student_head_action() {
  # We can't use parameter expansion on $PWD because of recursion
  local _dirname="${1%/*}"
  _dirname="${_dirname##*/}"

  [[ -d $1 ]] && return 0
  if ! [[ -w $1 && -f $1 ]]; then
     printf '%s\n' "$1 does not exist or is not writeable, skipping"
     return 1
  fi
  ed -s "$1" <<< $'0a\n'"//${_dirname}"$'\n.\n,s/\r//g\nw'
}

student_head() {
  local _file
  if (( $# )); then
     for _file; do
        student_head_action "${_file}" || _retval=1
     done
  else
     if shopt -qs globstar; then
        for _file in **/*; do
           student_head_action "${_file}" || _retval=1
        done
        shopt -u globstar
     else
        printf "%s\n" "Globstar isn't available, attempting to use GNU find ..."
        find . -type f -perm 644 -exec bash -c '
           _filepath={}
           _dirname=$_filepath
           _dirname="${_dirname%/*}"
           _dirname="${_dirname##*/}"
           echo $_dirname
           ed -s "$_filepath" <<< '"$'0a\n'"'"//${_dirname}"'"$'\n.\n,s/\r//g\nw'" \;
     fi
  fi
  return "${_retvalue-0}"

您可以student_head在文件夾中執行時自動將文件夾名稱作為標題添加到其中的可寫文件及其子目錄中:

student_head_action() {
   # We can't use parameter expansion on $PWD because of recursion
   local _dirname="${1%/*}"
   _dirname="${_dirname##*/}"

   [[ -d $1 ]] && return 0
   if ! [[ -w $1 && -f $1 ]]; then
       printf '%s\n' "$1 does not exist or is not writeable, skipping"
       return 1
   fi
   bash -c "ed -s {} <<< $'0a\n'"# Student: ${_dirname}"$'\n.\n,s/\r//g\nw'"
}

student_head() {

   local _file
   if (( $# )); then
       for _file; do
           student_head_action "${_file}" || _retval=1
       done
   else
       if shopt -s globstar > /dev/null 2>&1; then
           for _file in **/*; do
               student_head_action "${_file}" || _retval=1
           done
          shopt -u globstar
       else
           printf '%s\n' 'Globstar isn't available, attempting to use GNU find...'
           find . -type f -writable -exec bash -c '
               _dirname="${1%/*}\
               _dirname="${_dirname##*/}\
               ed -s "$1" <<< '"$'0a\n'"'"# Student: ${_dirname}"'"$'\n.\n,s/\r//g\nw'" {} \;
       fi                
   fi

   return "${_retval-0}"
}

~/.bashrc如果您希望使用者student_head在使用bash.

student_head可以通過兩種方式呼叫:

  1. 沒有爭論。在這種模式下,目前目錄及其子目錄中的所有可寫文件都帶有標頭檔。
  2. 以文件名作為參數。在這種模式下,只有參數中列出的文件才會有標題。

如果參數中的文件不存在,則student_head返回退出狀態 1。

需要說明的是,這個腳本使用globstar的是bash>=4.0.

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