我正在尝试修复一个 bash 脚本,该脚本应该:
- 转到目录 (RESULT_DIR)
- 从列表文件 (Names.txt) 中查找具有匹配名称的 csv 文件
- 根据在步骤 2 的文件中找到的 (Patterns.txt) 中列出的模式进行 Grep
- 获取该输出并将其存入 MatchingResults.txt
到目前为止,我收到“参数列表太长”错误。但我不知道如何解决这个问题。我希望得到有关如何修复它的帮助,因为我可能犯了我没有看到的错误。
#! /usr/bin/env bash
RESULT_DIR="$HOME/.../Results/"
NAMES="$HOME/.../Names.txt"
PATTERNS="$HOME/.../Patterns.txt"
cd "$RESULT_DIR" && grep -f "$PATTERNS" $(find $(cat "$NAMES").csv) >> MatchingResults.txt
更新:这是名称和模式的样子,这样您就可以更好地理解我的意思。抱歉缺少这个!
"NAMES"
"O60333"
"P52209"
"Q8N2Z9"
"O00230"
"O00273"
"O00468"
"O75381"
"Q86V15"
"E7ERA6"
"Q96HA4"
"K7EPZ7"
"H3BM07"
"H0YBK5"
"G8JLG8"
"Q13148"
"O00187"
和
"PATTERNS"
"R381P"
"T95A"
"E112K"
"R136G"
"R140Q"
"S149L"
"R173Q"
"S184A"
"E193G"
"V260M"
"P291L"
"H313Y"
"P328L"
RESULT_DIR 中的文件的名称如“A12345.csv”。
我期望cat "$NAMES"
会输出上面的 Names.txt 内容,以便可以将它们作为 的参数逐行读取grep -f patterns filestolookthrough
。
我想要做的$(find $(cat "$NAMES").csv)
是遍历名称以逐行匹配结果目录中的名称,然后grep -f pattern
仅匹配该特定匹配文件中的名称。
我的错误输出只说line 8: /usr/bin/find: Argument list too long
答案1
理想情况下,您应该添加更多详细信息和示例,例如 ::
(A) RESULT_DIR & NAMES & PATTERNS 的内容;
(B) 你认为cat "$NAMES"
会输出什么;
(C) 你认为$(find $(cat "$NAMES").csv)
会输出什么 [[ 重要:: 这不会将扩展名 .csv 添加到文件 $NAMES 中的所有名称!只有文件 $NAMES 中的最后一个条目才会获得扩展名 .csv! ]];
(D) 您得到的确切错误输出是什么; ....
如果没有这些细节,我们就必须猜测问题并给出解决方案。有了这些细节,我们也许能够真正拿出一个解决方案。
在等待您对问题进行更新之前,这里有 3 个关于正在发生的事情的猜测:
(1) NAMES 可能包含太多行并且find
得到的参数列表很长。
(2) NAMES 也可能包含很少的行,并且find
正在生成一个非常长的文件列表,而这会grep
获取一个非常长的参数列表。
(3) PATTERNS 的线条过多,但这不太可能。
(4) 结果可能完全是另一回事,但您必须用详细信息更新您的问题。
根据OP更新,这是一个解决方案:
我认为,NAMES 文件应该已经具有 .csv 扩展名;通过vim
或通过最初生成列表的脚本进行编辑很简单。这样,就不必错误地使用cat
.csv 并将其仅添加到最后一个条目。
此外,文件列表不需要引号。
接下来,模式文件不应该有引号,与所需的文本不匹配。
通过这些更改,给定的脚本将包含最后一行,其中.csv
被删除:
cd "$RESULT_DIR" && grep -f "$PATTERNS" $(find $(cat "$NAMES")) >> MatchingResults.txt
现在,如果 NAMES 始终位于 RESULT_DIR (或已知目录)内,则该 PATH 可以逐行包含在 NAMES 中;我们find
也可以消除。
进行此更改后,给定脚本的最后一行将是这样的:
cd "$RESULT_DIR" && grep -f "$PATTERNS" $(cat "$NAMES") >> MatchingResults.txt
建议 OP 在模式和名称中尝试使用一个小列表。有了这个工作,我们就可以继续xargs
在模式或名称中使用太多参数。
建议 OP 在执行脚本时还列出 PATTERNS & NAMES 中的大致行数以及确切的错误输出。
cat
更新:来自将find
引发错误的长列表。这是解决这个问题的方法:
cd“$RESULT_DIR” for fn in $(cat "$NAMES") #### "迭代 $NAMES 中列出的所有文件,确保 $NAMES 文件中没有引号" 做 grep -f“$PATTERNS”${fn}.csv ####“如果 $NAMES 文件已逐行包含 .csv,则无需添加 .csv,否则在此处添加” #grep -f "$PATTERNS" $(查找 ${fn}.csv) ####“或者使用此替代方案,以防 $NAMES 中的文件列表不是直接位于 $RESULT_DIR 内,而是位于某个子目录中” 完成 >> MatchingResults.txt
现在,没有find
也没有办法从find
about argument 中获取错误!
答案2
我想这就是你想要的。我假设 $NAMES 文件是需要添加 .csv 扩展名的文件名,然后对每个文件进行模式匹配。
cd "$RESULT_DIR" && sed 's/$/.csv/' "$NAMES" | xargs grep -Hf "$PATTERNS" >> MatchingResults.txt