【问题标题】:pass wildcard to cut command in shell script and store it in a variable将通配符传递给 shell 脚本中的剪切命令并将其存储在变量中
【发布时间】:2018-06-28 15:03:39
【问题描述】:

我是 shell 新手,我有一个案例,我正在尝试评估特定列的唯一值以检查它们在稍后将调用的 shell 脚本中是否有效。

从我的搜索来看,我认为 cut 和 sort & unique 是很好的做法

所以我的尝试是

file=/filepath/*vendor.csv
file_categories = `cut -d, -f1 $file |sort |unique`

$file 应该保存文件名中包含 vendor 的文件

但即使在使用命令替换 (`) 之后,$file 也没有被正确的文件名替换,它只是放置文件中存在的内容

我正在尝试的另一个例子是

a=/stage/scripts/vendor/*.out
echo $a
/stage/Scripts/ecommerce/oneclick/nohup.out /stage/Scripts/ecommerce/Vendor/Vendor_Automate_Ingestion_Process.out

wc-l

wc: /stage/Scripts/ecommerce/vendor/*.out:

$(wc -l "$a")
wc: /stage/Scripts/ecommerce/vendor/*.out:No such file or directory

我想了解如何在命令替换中传递通配符以及我可以做些什么来纠正。

【问题讨论】:

  • 请务必通过按checkmark sign 接受最能解决您的问题的答案(如果有)。这为回答最佳的受访者提供了 15 分的声誉。 Yoe 还可以对任何和所有有助于您理解问题的答案进行投票。请注意,不会从原始发布者的声望点中减去代表点(有些人似乎认为);-)。

标签: bash shell ksh glob cut


【解决方案1】:

不,file 将包含带有通配符的文字字符串。当您插入值 $file 时不带引号,这就是 shell 将其评估为通配符的时候。 echo "$file" 正确引用会显示变量的实际值。

没有很好的方法将文件名列表存储在常规 shell 变量中。 Ksh 和其他一些 shell 具有用于此目的的数组,但它不能移植回通用 sh 并且可能不是您实际需要的东西,具体取决于您要实现的最终目标。如果您想从与通配符匹配的文件中的字段中提取唯一值到字符串中,只需确保赋值中的等号周围没有空格即可。

file_categories=$(cut -d, -f1 $file | sort -u)
#              ^ no spaces around the equals sign!

在这里将通配符存储在变量中是可疑的;如果这是您要解决的问题,可能只需直接使用通配符即可。

在您不特别希望shell扩展通配符并标记字符串的任何地方,您都需要在其周围加上双引号。

echo "$file_categories"

这个字符串不是机器可读的,因此在变量中捕获它的用处有限。我赌一小笔钱,您实际上只是想直接显示输出而不是将其存储在变量中,这样您就可以echo 其值:

cut -d, -f1 /filepath/*vendor.csv | sort -u

如果您想遍历这些值,请将其进一步通过管道传递给 while read -r ...

【讨论】:

  • 因此,如果我在命令替换中传递 $ 变量,则会评估通配符,我的最终目标是评估特定列是否为有效的预定义值集,我想提取唯一值检查是否所有这些都有效与否,关于如何实现的任何建议?
  • 发布一个关于您的实际要求的新问题。这里有太多的事情要猜测(什么是有效的,数据是什么样的,等等)
  • 如果您有一个包含有效标签的文件,cut -f1 -d, *vendor.csv | grep -Fvxf valid.txt 将打印不在valid.txt 中的那些...但更有用的是,您可能需要一个 Awk 脚本来打印整行包含无效标签。我认为这种问题每周会被问几十次;查找重复项。
  • ,根据政策我必须等待90分钟才能再次发布问题,我不希望获取具有重复值的记录,我只想验证输入数据是否有效, 顺便说一句,当我使用 `cut -d, -f1 /filepath/*vendor.csv | sort -u` 出于某种原因它也会考虑标题
  • 感谢您的宝贵时间,我已在 (stackoverflow.com/questions/48341823/…) 中发布了一个单独的问题,如果您有时间请看一下
【解决方案2】:

为了使您的wc -l 命令正常工作,请这样调用它:

wc -l $a

不要引用a 变量,shell 需要扩展它来读取它的* 通配符值

【讨论】:

    猜你喜欢
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 2012-04-01
    相关资源
    最近更新 更多