我制作了一个 for 循环脚本,如下所示,
for file in *.csv
do
grep raxA $file > new_${file}
done &&
mkdir raxA && mv new_* raxA &&
for file in *.csv
do
grep raxB $file > new_${file}
done &&
mkdir raxB && mv new_* raxB &&
for file in *.csv
do
grep raxC $file > new_${file}
done &&
mkdir raxC && mv new_* raxC
当在中找到所有关键字时,此脚本将起作用数据集文件,但当文件中缺少任何一个关键字时,它会失败数据集文件。你能帮我完成这项工作吗?grepcsv 文件中缺少指定的关键字。先感谢您。
答案1
听起来你想要类似的东西:
mkdir -p raxA raxB raxC &&
awk '
/raxA/ {print > ("raxA/new_"FILENAME)}
/raxB/ {print > ("raxB/new_"FILENAME)}
/raxC/ {print > ("raxC/new_"FILENAME)}' ./*.csv
答案2
您的问题是在命令后使用 AND ( &&
) 运算符连接命令grep
。注意grep
!的退出状态
从man grep
:
退出状态
通常,如果选择了一行,则退出状态为 0;如果没有选择行,则退出状态为 1;如果发生错误,则退出状态为 2。
退出状态为 1 时,不会运行以下命令。看man bash
命令1 && 命令2
当且仅当 command1 返回退出状态为零(成功)时,command2 才会执行。
进一步提示:
- 您的
for
-loops 可以合并为一个 - 关键字可以成为
for
-loop 并与文件循环嵌套 - 首先创建目录并直接将输出重定向到那里以跳过
mv
答案3
正如其他人已经指出了您的命令的问题一样,我为您提供了一种使用 shell 循环执行操作的替代方法应该避免的。
您awk
还可以搜索模式并将每个匹配的模式拆分为多个文件。
awk '{ matched=match($0, /rax[ABC]/); };
matched{ dirname=substr($0, RSTART, RLENGTH);
system("mkdir -p " dirname);
print >(dirname"/new_"FILENAME);
matched=0;
}' infile
看man awk
为了match()
,substr()
,system()
功能。
由于您的文件似乎是 .csv,并且您可能想要在特定列而不是整行中查找模式,因此请添加-F,
到命令(指定输入文件的字段分隔符)并替换$0
(代表 中的整行awk
)与 .csv 文件中相应的列号匹配,例如匹配第一列中的模式,使用$1
,第二列使用$2
,第三列使用$3
,依此类推。