【问题标题】:Having trouble with a while loop in bash scriptbash脚本中的while循环有问题
【发布时间】:2020-02-17 04:28:59
【问题描述】:

我正在尝试在我的脚本中正确设置变量。基本上 x 和 y 变量应该在循环的每次迭代后增加 5。 a 值应该加一,并且循环应该迭代 $numResults 次数。

numResults 变量工作正常,并且循环确实尝试迭代该次数。我遇到了 4 组错误,因为这是存储在该变量中的数字。对于我的其他变量,当我用实数替换它们时,程序运行良好,但变量没有到位。

    #!/bin/bash

# An application that for each course with more than 50 students enrolled generates 
# an advisory report to warn of over-enrollment. It generates a text file from a user-defined 
# template which uses the following variables:
# 
# • [[dept_code]]
# • [[dept_name]]
# • [[course_name]]
# • [[course_start]]
# • [[course_end]]
# • [[credit_hours]]
# • [[num_students]]
# • [[course_num]] (the course number as specified in the filename of the .crs file)
# • [[date]]
#
# Create a new user-specified subdirectory for files
mkdir -p "$4"

numResults=$(grep -rE --include \*.crs -e "^[5][1-9]$" -e "^[6-9][0-9]$" -e "^[1-9][0-9][0-9]$" "$1" | gawk '{n++} END { print n }')

let i=0;
x=1
y=5
a=1
while [[ $i<="$numResults" ]]
do
# Gets the course code and number to use as the output file name && stores course_num to the output file temporarily for retrieval
file=$(grep -rE --include \*.crs -e "^[5][1-9]$" -e "^[6-9][0-9]$" -e "^[1-9][0-9][0-9]$" "$1" | sed -E 's/.*([A-Z]{3})([0-9]{4})\.*crs:[0-9][0-9]/\1\2/g' | gawk 'NR==$a { print; echo "" }')
course=$(echo $file | sed 's/[A-Z]//g')
(cat "$2"; echo ""; echo "$course";) > "$4/$file"


# Locate all files in the data directory with the .crs extension that also contain a line with 
# only a string "51" - "999" and grabs the contents of that file and stores them to the new 
# output file temporarily for retrieval
grep -hrEB 4 --include \*.crs -e "^[5][1-9]$" -e "^[6-9][0-9]$" -e "^[1-9][0-9][0-9]$" "$1" | gawk 'NR==$x,NR==$y{print}' >> "$4"/$file


# Create variables to hold the dept and course info
varCNum=$(gawk -v n=6 '{saved[FNR % n] = $0} ENDFILE {if (FNR >= n) print saved[(FNR + 1) % n]}' "$4"/$file)

varDC=$(gawk -v n=5 '{saved[FNR % n] = $1} ENDFILE {if (FNR >= n) print saved[(FNR + 1) % n]}' "$4"/$file)
varDN=$(gawk -v n=5 '{saved[FNR % n] = $0} ENDFILE {if (FNR >= n) print saved[(FNR + 1) % n]}' "$4"/$file | gawk '{for(i=2;i<=NF;i++){printf "%s", $i};}')

varCN=$(gawk -v n=4 '{saved[FNR % n] = $0} ENDFILE {if (FNR >= n) print saved[(FNR + 1) % n]}' "$4"/$file)
varCS=$(gawk -v n=3 '{saved[FNR % n] = $2} ENDFILE {if (FNR >= n) print saved[(FNR + 1) % n]}' "$4"/$file)
varCE=$(gawk -v n=3 '{saved[FNR % n] = $3} ENDFILE {if (FNR >= n) print saved[(FNR + 1) % n]}' "$4"/$file)
varCH=$(gawk -v n=2 '{saved[FNR % n] = $0} ENDFILE {if (FNR >= n) print saved[(FNR + 1) % n]}' "$4"/$file)

varNS=$(gawk -v n=1 '{saved[FNR % n] = $0} ENDFILE {if (FNR >= n) print saved[(FNR + 1) % n]}' "$4"/$file)


# Substitute the variables into the output file && and clean up
sed -E "s/\[\[ dept_code \]\]/$varDC/g; s/\[\[ dept_name \]\]/$varDN/g; 
s@\[\[ course_name \]\]@$varCN@g; s@\[\[ course_start \]\]@$varCS@g; s@\[\[ course_end \]\]@$varCE@g;
s@\[\[ credit_hours \]\]@$varCH@g; s@\[\[ num_students \]\]@$varNS@g; 
s@\[\[ course_num \]\]@$varCNum@g; s@\[\[ date \]\]@$varDate@g;" "$4"/$file | sed -e :a -e '$d;N;2,6ba' -e 'P;D'

let i+=1
let x+=5
let y+=5
let a+=1

done

我将以下参数传递给我的脚本: $ ./assign4.sh ./data assign4.template 12/16/2021 ./output

Which gives the following error message "./assign4.sh: line 31: ./output: Is a directory
./assign4.sh: line 37: ./output: Is a directory
gawk: warning: command line argument `./output' is a directory: skipped"

【问题讨论】:

  • 您应该避免在 bash 中使用旧的和已弃用的反向抽动。像这样使用括号 numResults=$(grep -rE --include .....)
  • 除了 Jotne 提到的。恕我直言,您的问题不清楚,请通过仅编辑其中需要的详细信息来保持您的问题简单,请进行编辑并告诉我们。
  • @duckyPluck,请检查您的参数,一旦它们看起来没有正确传递?或者您尝试将带有绝对路径的文件名传递给 ot 一次?让我知道它是怎么回事。
  • @duckyPluck,没有 shell 变量不能通过这种方式在 awk 中工作,像 gawk -v var="$a" 'NR==var {print}' Input_file 这样的东西应该可以工作。其中a="shell_variable" 是shell 变量。
  • 啊啊,我明白了。傻我,我以为它可以在 awk 中看到 shell 变量。不过,这现在很有意义,谢谢。

标签: bash loops awk while-loop scripting


【解决方案1】:

虽然您的要求并不完全清楚,但通过看到您的错误,您可能需要传递要捕获输出等的目录/文件的完整路径。

./assign4.sh "/your_complete_path/data assign4.template" "12/16/2021" "/your_complete_path/output"

我还将参数包装在" 中以避免任何混淆,以防您的目录名称中有任何空格,它会避免它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 2014-12-19
    • 2013-03-10
    相关资源
    最近更新 更多