linux - Bash 脚本执行所需的帮助

标签 linux bash shell

我有一个脚本,可以从文件中提取逗号分隔的信息并准备更新语句。该文件设置如下所示:

ID,NAME,DATE,TIME,HOURS,EMPNUMBER
1, Joe, 12/11, 12:45, 5, 333
2, John, 12/12, 16:45, 7, 666

我的脚本将一个文件作为参数并从命令行运行,如下所示:

./runScript.sh file.csv

我的脚本代码如下:

for i in ` cat $1 | grep -v “EMPNUMBER” | cut -d',' -f4,5`
do
   time=`echo $i | cut -d',' -f1`
   hours=`echo $i | cut -d',' -f2`
   echo "update jobs.j j set j.time= $time where j.hours=$hours;"

done

我很好奇为什么当我运行我的脚本时它会跳过我文件中的第一行,即标题信息。显然,这是预期的效果,但为了让我的学习取得进展,我需要了解为什么从文件中跳过第一行。

有人可以帮助我理解吗? ~

最佳答案

如果你正在学习 bash,那么除了解释 grep -v "EMPNUM"是导致 header 被跳过的原因(-v 选项表示查找不包含 EMPNUM 的行),还有一些其他项目需要指出。首先,好的 bash 代码利用 bash 提供的工具来读取输入和解析数据,而不是依赖生成子 shell 来运行其他程序(即 cat, grep, cut)。

注意:使用 cat, grep, cut 没有任何问题,但认识到 bash 本身提供的工具可以完全满足您使用这 3 个其他程序的目的,这将增强您的编程技能。

首先,bash 提供了内置的 read用于从 stdin 读取数据或任何其他文件。要读取文件,您通常会看到 while read var1 var2; do... done <"filename"而不是 for i in $(cat file) - 因为许多的原因。接下来,而不是调用 cut... , bash 提供 parameter expansion/substring extraction处理将任何文本行解析为任何单个变量。此外,通过选择伴随 read 的变量明智地,您可以消除使用 substring extraction 的需要完全。

下面显示了使用 bash 替代 cat, grep, cut您的示例中显示的方法。如果有兴趣学习bash ,看看它,如果您有任何问题,请告诉我。您可以使用 echoprintf可互换输出。同时 echo一般比较简单,printf提供了许多优点。两者都值得学习...

#!/bin/bash

## set the datafile name (defaults to 'dat/empdata.dat')
dfn="${1:-dat/empdata.dat}"

## validate that file is readable
[ -r "$dfn" ] || {
    printf "\n error: file not readable '%s'. Usage: %s [filename (dat/empdata.dat)]\n\n" "$dfn" "${0//*\//}"
    exit 1
}

## simple output header for data
printf "\nEmployee data read from file: '%s'\n\n" "$dfn"

## read each line in file, skipping header (where $id = ID)
#  IFS is set to include ',' in addition to default ' \t\n'
while IFS=$' ,\t\n' read -r id nm dt tm hrs eno || [ -n "$hrs" ]; do

    # if header row - skip
    [ "$id" = "ID" ] && continue
    # print out each of the values for the employee
    printf "ID: %s  NAME: %-4s  DATE: %s  TIME: %s  HOURS: %s  EMPNUMBER: %s\n" \
    "$id" "$nm" "$dt" "$tm" "$hrs" "$eno"

done <"$dfn"

输入文件:

$ cat dat/empdata.dat
ID,NAME,DATE,TIME,HOURS,EMPNUMBER
1, Joe, 12/11, 12:45, 5, 333
2, John, 12/12, 16:45, 7, 666

输出:

$ bash empdata.sh

Employee data read from file: 'dat/empdata.dat'

ID: 1  NAME: Joe   DATE: 12/11  TIME: 12:45  HOURS: 5  EMPNUMBER: 333
ID: 2  NAME: John  DATE: 12/12  TIME: 16:45  HOURS: 7  EMPNUMBER: 666

关于linux - Bash 脚本执行所需的帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26705860/

相关文章:

linux - 在 bash 中使用/home/directory 从所有用户创建菜单

bash - 检查两行是否以相同的字符开头,如果是则输出平均值,如果不是则打印实际值

bash - "for loop"和 $() 组合限制

linux - 如何在 bash 编程循环中对文件使用 stat

c++ - Linux进程分配的内存使用情况

php $fopen 错误

linux - 如何等到 shell 脚本启动的所有内容结束?

c# - Mac 和 Linux 上类似 Windows 的 shell 扩展

linux - CMake:使用 MinGW 交叉编译 linux-to-windows 没有找到一些系统头文件

c++ - 如何避免多重定义链接错误?