我是一名评分员,提交给我的文件最终存放在一个以学生姓名命名的文件夹中,该文件夹本身位于我的 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}"
答案1
您可以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
可以通过两种方式调用:
- 毫无争议。在此模式下,当前目录及其子目录中的所有可写文件都预先添加了标头。
- 以文件名作为参数。在此模式下,只有参数中列出的文件才会预先添加标头。
如果参数中的文件不存在,student_head
则返回退出状态 1。
应该提到的是,该脚本使用globstar
,这需要bash>=4.0
.
答案2
find
这是结合和 的解决方案ed
。
add_header() {
declare regex IFS='|'
(( $# )) && regex="^($*)$" || regex=""
find "$PWD" -type f -exec bash -c '
( exec grep -E -qs -e "$0" <<<"${1##*/}" ) || exit
_dirname="${1%/*}"
_dirname="${_dirname##*/}"
exec ed -s "${1}" <<EOF
0a
# Student: ${_dirname}
.
wq
EOF
' "${regex:-.+}" '{}' \;
return 0
}
add_header # all files in current directory recursively
add_header file1 file2 file3 # only named files in current directory recursively