用于查找和替换 csv 文件中的值的 Shell 脚本

用于查找和替换 csv 文件中的值的 Shell 脚本

我正在尝试编写一个 shell 脚本来搜索 csv 文件中的单元格值并替换同一行中的相应单元格。

下面是我的 csv 文件 ( report.csv)

#,设备,状态
1、设备 1、已使用
2、设备 2、免费
3、设备 3、免费

这就是我想做的:

用户在执行脚本时将输入设备名称作为输入。

例如,输入设备名称:
用户输入“Device2”

下一步:脚本应该搜索设备2report.csv。如果发现设备2,检查中的值地位与其对应的列,如果值为自由的,将其替换为用过的,否则退出脚本设备2已在使用中

我尝试过以下代码

#!/bin/bash
dvc=""
FILE_HOME="/tmp/test/"

update_value () {  
  awk -F, -v d="$dvc" '$2==d{if($3=="Free")$3="Used"; else print d "In use"; input_value;}1' \
      OFS=, "$FILE_HOME"/report.csv > "$FILE_HOME"/report1.csv  
  mv "$FILE_HOME"/report1.csv "$FILE_HOME"/report.csv
}

input_value () {
  echo -e "Enter the device name:\n"
  read dvc
  update_value
}

input_value

这段代码很好,当如果声明是真的
但当如果声明是错误的,它不是input_value从 else 部分调用函数。它只是打印设备# 正在使用与 csv 文件中的其他条目一起添加到新文件中。

我得到以下输出文件

  • 当输入是设备2:

    #,设备,状态
    1、设备 1、已使用
    2、设备 2、已使用
    3、设备 3、空闲

  • 当输入是设备1:

    #,设备,状态
    设备 1 正在使用
    1、设备 1、已使用
    2、设备 2、空闲
    3、设备 3、空闲

这是我正在做的正确方法吗?
我很高兴看到是否有不同/更好的方法来实现要求。

答案1

将您的错误消息写入stderr.

awk -F, OFS=, -v d="$dvc" '
    $2==d {
      if($3=="Free") $3="Used"
      else print d "In use" > "/dev/stderr"
      print
    }' $FILE_HOME/report.csv > $FILE_HOME/report1.csv

这将使其显示在屏幕上(如果stderr未重定向),而不是显示在标准输出中。

话虽这么说,您可以采取一些措施来使脚本更易于使用。这个怎么样:

#!/usr/bin/awk -f
BEGIN {
  FS=","
  OFS=","
  FILE_NAME="/tmp/test/report1.csv"
  print "Enter the device name:"
  getline d < "-"
}

$2==d && $3=="Free" {
  $3="Used"
  print > FILE_NAME
  next
}

$2==d {
  print d " in use" > "/dev/stderr"
}

{
  print > FILE_NAME
}

调用它

$ script_name /tmp/test/report.csv

和/或bash根据需要将其包裹起来。

答案2

您仅限于 shell 和 awk 吗?你能使用 SQLite 来存储你的数据或者至少解析它吗?

sqlite> .mode csv
sqlite> .import report.csv report
sqlite> update report set status="Used" where Device="Device2";
sqlite> select * from report;
 1,Device1,Used
 2,Device2,Used
 3,Device3,Free

或者您可以使用更通用的编程语言(例如 Python)来完成您的任务?

import csv

with open('report.csv') as csvfile:
  reader = csv.DictReader(csvfile)
  for row in reader:
    if row['Device'] == "Device3":
      row['Status'] = "Used"
    print row

{'Device': 'Device1', 'Status': 'Used', '#': '1'}
{'Device': 'Device2', 'Status': 'Free', '#': '2'}
{'Device': 'Device3', 'Status': 'Used', '#': '3'}

相关内容