【问题标题】:Shell script if statement variable comparison issues [duplicate]Shell脚本if语句变量比较问题[重复]
【发布时间】:2018-10-03 01:20:21
【问题描述】:

我有以下 shell 脚本将标题行附加到一批 .csv 文件。我需要根据输入 csv 中的列数对每个 .csv 应用不同的标头 txt 文件。该脚本正在工作,因为它正在应用头文件并输出新的 csv,但每个文件都获取“else”头 - 包括使用csvgrep -n $f | wc -l 命令评估为“91”的 csv。

#!/bin/sh

dir="/Users/XXX/xlsxtocsv"

#move to the csvraw output directory
cd csvraw/

#append the header row needed for DB import
for f in *.csv; do 
    if [[ "csvgrep -n $f | wc -l" == 91 ]]; then
       cat $dir/svcheader3col.txt $f >> "$dir/csvhead/${f%}header.csv"
    else
       cat $dir/svcheader.txt $f >> "$dir/csvhead/${f%}header.csv"
    fi

done

当我在 csv 文件上手动运行 csvgrep 命令时,我得到:

username:csvraw username$ csvgrep -n file4col.csv | wc -l
      92
username:csvraw username$ csvgrep -n file3col.csv | wc -l
      91

为什么“file3col.csv”文件在 if 语句中没有计算为 91,而是当我手动运行它时?

【问题讨论】:

  • 比较的是字符串csvgrep -n $f | wc -l,而不是命令csvgrep -n $f | wc -l的输出。
  • 顺便说一句,考虑使用bash -x yourscript 来运行一个脚本,记录它调用的每个命令——如果你真的看到测试在实践中做了什么,这使得这种问题更容易调试。
  • 我不知道有很大帮助的“bash -x”。

标签: shell csv for-loop if-statement


【解决方案1】:

您实际上并没有运行csvgrep 命令。使用诸如$(...) 之类的命令替换来执行此操作。

#!/bin/bash
: "${dir?dir must be defined}"
for f in *.csv; do 
    if [[ "$(csvgrep -n "$f" | wc -l | tr -d '[:space:]')" = 91 ]]; then
       cat -- "$dir/svcheader3col.txt" "$f" 
    else
       cat -- "$dir/svcheader.txt" "$f"
    fi >> "$dir/csvhead/${f%.csv}header.csv"
done

【讨论】:

  • 这工作得更好,我明白我做错了什么。 'bash -x' 输出以下内容,这似乎没有让 'wc -l' 部分正确。 '92' 和 '91' 前面的空格是否也把事情搞砸了? '+ for f in '.csv' '++ csvgrep -n file4col.csv '++ wc -l '+ [[ 92 == 91 ]] '+ cat -- /Users/xlsxtocsv/svcheader.txt file4col.csv '+ for f in '.csv' '++ csvgrep -n file3col.csv '++ wc -l '+ [[ 91 == 91 ]] '+ cat -- /Users/xlsxtocsv /svcheader.txt file3col.csv
  • 你能反引号吗?已格式化,*s 被视为格式化。 (也就是说,较长的日志可能更容易以gist 的形式发布,因此多行格式保持不变)。也就是说,在我看来,它正在从该日志中做它应该做的事情。 (请注意,%.csv 表示此代码正在将输出写入CNY04-3colheader.csv,而不是原始代码中的CNY04-3col.csvheader.csv)。
  • 什么空格? [[ 92 == 91 ]] 正是它应该的样子。空格在测试操作中是强制性的——请记住[ 是一个命令,而不是 shell 语法,并且命令与它们的参数用空格分隔。 ([[ ]] 实际上是语法,但空格仍然是强制性的)。如果您的数据中有空格,那么bash -x 日志会将其显示为类似于[[ ' 91' == 92 ]]
  • (顺便说一句,= 而不是 == 在这个答案是故意的:== 是一个不可移植的扩展,而 = 作为字符串比较运算符即使在基线 POSIX test 中也有效/[;见pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html)
  • 这是带有空格的 bash -x 输出形式。我仍然不确定如何正确评估'91。 gist.github.com/jamierob/d18f3d751893a416b6acae919cf9b3ea
猜你喜欢
  • 1970-01-01
  • 2014-10-09
  • 1970-01-01
  • 1970-01-01
  • 2017-12-03
  • 2021-07-26
  • 2014-02-07
  • 2013-12-14
  • 1970-01-01
相关资源
最近更新 更多