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

从文件读取内容后在awk中使用变量的脚本问题排查

解决Bash脚本提取文件名字段的问题

首先,咱们先拆解你脚本里的两个典型问题:

错误1:重定向语法写错了

你第一个awk命令里用了<<<<<"$FILE"——这多打了两个<!正确的Here字符串语法是<<<,用来把变量内容直接作为awk的标准输入。多出来的<会被bash当成文件重定向操作,导致它找不到对应的文件,所以才会抛出/ : No such file or directory的错误。

错误2:awk没正确处理你传递的变量

第二个awk命令你用-v var="${FILE}"传递了文件名变量,但你的awk脚本里根本没用到var!这时候awk会默认从标准输入读取数据——也就是整个zips_not_received.csv文件,所以每次循环它都会输出所有行的第二个字段,导致你看到重复的bar2、bar1。


推荐解决方案:用Bash内置字符串处理(更高效)

没必要每次循环都调用awk(外部进程),Bash本身就有强大的字符串拆分能力,速度更快还减少资源消耗:

#!/bin/bash
while read -r FILE; do
    echo "$FILE"
    # 提取host:从开头到第一个下划线之前的部分
    host="${FILE%%_*}"
    # 提取fp:先去掉第一个下划线及之前的内容,再取到下一个下划线之前的部分
    fp="${FILE#*_}"
    fp="${fp%%_*}"
    echo "$host"
    echo "$fp"
done < zips_not_received.csv

语法小解释:

  • ${var%%pattern}:从变量末尾开始删除最长匹配pattern的内容,这里_*匹配第一个下划线及后面所有字符,剩下的就是foop07这类host值。
  • ${var#*pattern}:从变量开头删除最短匹配pattern的内容,这里*_匹配第一个下划线及之前的字符,剩下的是bar2_20190423152612.zip,再用%%_*就得到bar2这类fp值。

如果你习惯用awk的修正版本

要是你更倾向于用awk,那得修正输入传递的方式:

#!/bin/bash
while read -r FILE; do
    echo "$FILE"
    # 用<<<正确把变量内容传给awk
    host=$(awk 'BEGIN { FS = "_" } { print $1 }' <<< "$FILE")
    echo "$host"
    # 同样用<<<传递输入,或者用split处理变量
    fp=$(awk 'BEGIN { FS = "_" } { print $2 }' <<< "$FILE")
    # 另一种用-v传递变量并拆分的写法:
    # fp=$(awk -v file="$FILE" 'BEGIN { FS="_"; split(file, arr, "_"); print arr[2] }')
    echo "$fp"
done < zips_not_received.csv

这样修改后,就能得到你预期的输出了,之后你就可以在循环里用$host和$fp执行ssh命令获取对应文件啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:31:52