You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash中read -r遍历CSV文件仅处理首行的问题求助

问题:Bash脚本中read -r仅处理CSV第一行的原因

原本以为read -r会逐行处理CSV内容,但实际只跑了第一行就停了,试着重定向去掉也没用。以下是我的Bash脚本:

#!/bin/bash
while IFS=, read -r a b c; do
        d=$(echo "$c"|cut -d' ' -f1)
        for node in $(seq -f "somehost%02.0f" 01 29); do ssh -i ~/file.key  user@$node "zgrep $a /path/*$(date -d $d +'%Y-%m-%d')*"; done >> tmp
done < New.csv

对应的CSV文件内容:

0000007415597221,Authorized,11-SEP-23 10.40.27.000000 AM
0000007415596310,Authorized,11-SEP-23 10.40.30.000000 AM
0000007415596319,Authorized,11-SEP-23 10.40.31.000000 AM
0000007438025843,Authorized,17-SEP-23 05.56.34.000000 PM
0000007442152893,Authorized,18-SEP-23 07.36.24.000000 PM
0000007442154377,Authorized,18-SEP-23 07.36.34.000000 PM

原因与解决办法

核心问题是**ssh会占用脚本的标准输入**。

你的while循环通过< New.csv把CSV文件作为标准输入,但循环内的ssh命令默认会继承这个输入源。第一次循环执行ssh时,它会把CSV里剩下的所有内容都当作自己的输入消耗掉,后续的read命令就没有内容可读,循环直接终止。

两种修复方式:

  1. 给ssh添加-n参数:该参数会将ssh的标准输入重定向到/dev/null,避免它消耗CSV的输入流。修改后的ssh命令如下:

    ssh -n -i ~/file.key user@$node "zgrep $a /path/*$(date -d $d +'%Y-%m-%d')*"
    
  2. 使用非默认文件描述符读取CSV:把CSV文件绑定到非0的文件描述符(比如3),让read从这个描述符读取内容,避开ssh的干扰。修改后的脚本:

    #!/bin/bash
    while IFS=, read -r a b c <&3; do
            d=${c%% *}  # 替换echo+cut,用参数扩展更高效
            for node in $(seq -f "somehost%02g" 1 29); do 
                ssh -i ~/file.key user@$node "zgrep $a /path/*$(date -d $d +'%Y-%m-%d')*"
            done >> tmp
    done 3< New.csv
    

顺便提两个小优化:

  • 提取日期部分d可以用参数扩展${c%% *},无需启动额外进程,比echo "$c"|cut更高效。
  • seq的%02.0f可简化为%02g,起始值写1即可自动补前导零,写法更简洁。

内容的提问来源于stack exchange,提问作者imp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:20:04