You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Shell脚本批量合并文件内容(排除首行)仅复制首个文件的问题求助

Shell脚本批量合并文件内容(排除首行)仅复制首个文件的问题求助

嗨,我来帮你分析问题并给出解决方案~

你遇到的核心问题出在shell通配符的展开时机上:当你输入./copy.sh ./folder/*.csv newfile.csv时,你的shell会先把./folder/*.csv展开成所有匹配的CSV文件名列表,比如变成./copy.sh file1.csv file2.csv file3.csv newfile.csv。这时候脚本拿到的参数并不是你以为的$1=./folder/*.csv$2=newfile.csv,而是$1=file1.csv$2=file2.csv$3=file3.csv$4=newfile.csv

而你原来的脚本里把FILES=$1,相当于只取了第一个文件名,自然只会处理第一个文件;同时DESTINATION=$2还把第二个文件当成了目标文件,完全偏离了你的预期。

下面给你两种修正后的脚本方案:

方案一:简洁版(适合文件名无空格的场景)

#!/bin/sh

# 先检查参数数量是否足够
if [ $# -lt 2 ]; then
    echo "用法:$0 <要合并的文件列表> <目标文件>"
    exit 1
fi

# 把最后一个参数设为目标文件
DESTINATION=${!#}
# 把前面所有参数作为要处理的文件列表
FILES=${@:1:$#-1}

for f in $FILES
do
    echo "正在处理文件: $f"
    awk 'NR>=2' "$f" >> "$DESTINATION"
done

方案二:安全数组版(支持文件名带空格/特殊字符)

#!/bin/sh

# 参数校验:至少需要传入源文件+目标文件两个参数
if [ $# -lt 2 ]; then
    echo "用法:$0 <要合并的文件1> <要合并的文件2> ... <目标文件>"
    exit 1
fi

# 提取最后一个参数作为目标文件
DESTINATION="${@: -1}"
# 提取除最后一个外的所有参数作为源文件数组
FILES=("${@:1:$#-1}")

# 遍历每个源文件处理
for f in "${FILES[@]}"
do
    echo "正在处理文件: $f"
    awk 'NR>=2' "$f" >> "$DESTINATION"
done

使用说明

直接用你原来的调用方式即可:

./copy.sh ./folder/*.csv newfile.csv

这次shell展开通配符后,脚本会自动把前面所有CSV文件当成源文件,最后一个newfile.csv作为目标文件,完美实现“排除首行批量合并”的需求~

另外提醒下:给变量加双引号(比如"$f""$DESTINATION")很关键,能避免文件名含空格、特殊字符时出现错误。

备注:内容来源于stack exchange,提问作者k88074

火山引擎 最新活动