linux - 将脚本更改为 For Do Done 循环

标签 linux bash for-loop awk

我有一个脚本需要变成一个循环,当我像下面的例子一样输入文件名时,该脚本完全按照我的需要工作(我的 Awk-fu 非常弱,所以很好)。

#!/bin/bash
awk -v FS='(<LastName>|<\/LastName>)' '{print $2}' 17822624.xml >> test.csv
awk -v FS='(<FirstName>|<\/FirstName>)' '{print $2}' 17822624.xml >> test.csv
awk -v FS='(<Id>|<\/Id>)' '{print $2}' 17822624.xml >> test.csv
awk -v FS='(<Dob>|<\/Dob>)' '{print $2}' 17822624.xml >> test.csv
awk -v FS='(<TestDate>|<\/TestDate>)' '{print $2}' 17822624.xml >> test.csv
#this awk command is different because their are multiple different values i need it to pull back
awk -F '<Value>|<\/Value>' '{for (i=2; i<=NF; i+=2) print $i}' 17822624.xml >> test.csv
cat test.csv | tr '\n' ',' > test2.csv
awk 'BEGIN{RS=ORS=','} {sub(/ ..:..:..$/,'')} !seen[$0]++' test2.csv > test3.csv

当我将它转换为 for do done 循环时,我遇到了问题。我相信这与单引号与双引号以及 ) 与 { 有关。但我正在尝试很多不同的事情,但运气不佳。

这是我创建的循环

#!/bin/bash
#file location
XMLDIR='/home/amoore19/XML/00581-001/scores'
NEWXML='/home/amoore19/XML/00581-001'

#this gives me the filenames without the path
for file in `ls ${XMLDIR}/*.xml | xargs -n1 basename`
do
awk -v FS='(<LastName>|<\/LastName>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -v FS='(<FirstName>|<\/FirstName>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -v FS='(<Id>|<\/Id>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -v FS='(<Dob>|<\/Dob>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -v FS='(<TestDate>|<\/TestDate>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -F '<Value>|<\/Value>' '{for (i=2; i<=NF; i+=2) print $i}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
"${NEWXML}/${file}" | tr '\n' ',' > "${NEWXML}/1${file}"
awk "BEGIN{RS=ORS=,} {sub(/..:..:..$/,"")} !seen[$0]++" "${NEWXML}/1${file}" > "${NEWXML}/2${file}"
done

这是我得到的错误:我曾尝试将单引号换成双引号,但运气并不好

$ ./ifthen.sh 
ls: /home/amoore19/XML/00581-001/scores/*.xml: No such file or directory
basename: missing operand
Try `basename --help' for more information.

就像我说的上面的例子效果很好,但我需要能够循环访问一个文件夹中的多个文件。

我知道这很丑陋,我知道 awk 可以自己在一个循环中完成所有事情,但我不知道如何创建它。有一天我会的,但现在这是我能做的最好的,我真的可以使用一些帮助/指导来了解我的循环有什么问题。

谢谢

更新

我在使用 shellcheck 后尽可能地更新了代码。仍然收到提到的错误。

新更新

所以我想我发现了我的问题,但我不明白为什么会出现问题?我做了一个新的 bash 脚本,它简单地执行了一个 cd 到目录,但它仍然说它不存在。如果我只对/home/amoore19/XML 执行此操作,它就可以工作,但是有关文件夹名称 00581-001 的问题导致了我的问题...有什么想法吗?

最后更新 我删除了 00581-001 文件夹并重新创建它并将文件移回原处,我不再收到错误...我猜它以某种方式损坏了? (我在娱乐时不小心给它加了一个额外的0)

这是当前的工作脚本:

#!/bin/bash
#file location
XMLDIR='/home/amoore19/XML/000581-001/scores'
NEWXML='/home/amoore19/XML/000581-001'

#this gives me the filenames without the path
for file in `ls ${XMLDIR}/*.xml | xargs -n1 basename`
do
awk -v FS='(<LastName>|<\/LastName>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -v FS='(<FirstName>|<\/FirstName>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -v FS='(<Id>|<\/Id>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -v FS='(<Dob>|<\/Dob>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -v FS='(<TestDate>|<\/TestDate>)' '{print $2}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
awk -F '<Value>|<\/Value>' '{for (i=2; i<=NF; i+=2) print $i}' "${XMLDIR}/${file}" >> "${NEWXML}/${file}"
"${NEWXML}/${file}" | tr '\n' ',' > "${NEWXML}/1${file}"
awk "BEGIN{RS=ORS=,} {sub(/..:..:..$/,"")} !seen[$0]++" "${NEWXML}/1${file}" > "${NEWXML}/2${file}"
done

感谢大家的帮助,shellcheck 帮助我知道我的脚本没有错,然后其他人都说该目录不存在(即使我知道它存在)帮助我确定文件夹

最佳答案

该目录中可能没有任何 XML 文件,因此 shell 扩展将只是 ${XMLDIR}/*.xml。您可以尝试使用 find 代替:

find ${XMLDIR}/*.xml -exec `basename` | while read file; do
...
...
done

关于linux - 将脚本更改为 For Do Done 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30856089/

相关文章:

linux - 如果未指定文件,为什么 grep 不起作用?

c - fork() 的工作

linux - 如何跟踪后台运行的shell脚本?

bash - 编写嵌套 shell 脚本 - 无法传递参数

javascript - for 循环参数在 JavaScript 中无法正常工作

linux - Bash 脚本查找和复制具有多个扩展名的文件,包括具有 2 个或 3 个扩展名的文件

node.js - Aws Ubuntu 上的 NodeJs 应用程序在 ipv6 上运行

bash - 如何在调试过程中交互式地修改 shell 脚本?

linux - Bash 脚本检查条件

javascript - 将数字添加到对象返回 NaN