Некоторые комментарии и несколько указателей:
Было бы полезно добавить «комментарии» для каждой строки кода, которая не является самоочевидной; то есть код типа mv f f.bak
не нужно комментировать, но я не уверен, какова цель ваших многочисленных строк кода.
Вы вставляете комментарий с символом '#', например
# concatenate all files that contain the word CREDITS into a file called rsh1
find ~/2011/Fall/StudentsRecord -name "*.rec" | xargs grep -l 'CREDITS' | xargs cat > rsh1
Также обратите внимание, что вы постоянно используете все прописные буквы для своих целей поиска, то есть CREDITS, когда ваши файлы примеров показывают смешанный регистр. Либо используется правильный регистр для ваших целей поиска, т.е.
`grep -l 'Credits'`
ИЛИ сказать grep -i (регистр gnore), т.е.
`grep -il 'Credits'
Ваша линия
sed -n /COURSE/p rsh1 | sed 's/COURSE NAME: //g' >> rsh2
можно уменьшить до 1 обращения к sed (и у вас происходит то же самое, что и в случае с запутанностью), попробуйте
sed -n '/COURSE/i{;s/COURSE NAME: //gip;}' rsh1 >> rsh2
Это означает (-n
по умолчанию не печатать каждую строку),
`gip` = global substitute,
= ignore case in matching
print only lines where substituion was made
Таким образом, вы редактируете строку ИМЯ КУРСА для любой строки, в которой есть КУРС, и печатаете только эти строки '(вам, вероятно, не нужен спецификатор' g '(глобальный), учитывая, что вы ожидаете только 1 экземпляр за строку)
Ваша линия
sed -e :a -e '{N; s/\n/ /g; ta}' rsh2 > rshf
На самом деле выглядит довольно неплохо, очень продвинуто, вы пытаетесь «сложить» каждые 2 строки в одну строку, верно?
Но,
sed '/COURSE/d;/CREDIT/d' rsh1 | sort -uk 1,1 | cut -d' ' -f1 | paste -d' ' >> rshf
Я действительно смущен этим, вы пытаетесь подсчитать баллы студентов? (со встроенным видом, я думаю, нет). Почему вы думаете, что вам нужна сортировка,
Хотя можно выполнять арифметику в sed, это очень сложно, поэтому вы можете либо использовать переменные bash для вычисления значений, либо использовать инструмент unix, предназначенный для обработки текста и выполнения логических и математических операций здесь представлены данные, awk или perl
В любом случае, одним из решений для подсчета каждого балла является использование awk
echo "123456 1 1 0 1 1 0 1 0 0 0 1 5 8 0 12 10 25" |\
awk '{for (i=2;i<=NF;i++) { tot+=$i }; print $1 "\t" tot }'
Даст вам подсказку, как поступить в этом направлении.
Awk имеет предопределенные переменные, которые он заполняет для каждого файла и каждой строки текста, которую он читает, т.е.
$0 = complete line of text (as defined by the internal variables RS (RecordSeparator)
which defaults to '\n' new-line char, the unix end-of-line char
$1 = first field in text (as defined by the internal variables FS (FieldSeparator)
which defaults to (possibly multiple) space chars OR tab char
a line with 2 connected spaces chars and 1 tab char has 3 fields)
NF = Number(of)Fields in current line of data (again fields defined by value of FS as
described above)
(there are many others, besides, $0, $n, $NF, $FS, $RS).
Вы можете программно увеличивать значения, такие как $ 1, $ 2, $ 3, используя переменную, как в примере кода, например, $ i (i - это переменная с числом от 2 до NF. Ведущий '$'
говорит, дайте мне значение поля я (то есть $ 2, $ 3, $ 4 ...)
Кстати, ваша проблема может быть легко решена с помощью одного сценария awk, но, очевидно, вы должны узнать о cat, cut, grep
и т. Д., Что является очень стоящей целью.
Надеюсь, это поможет.