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

相同命令处理不同换行符文本输出异常,如何修复?

兼容LF/CRLF换行符的脚本修改方案

问题描述

我有两个文本文件file1.txt和file2.txt,结构一致:

site_j-hostname1
<output of ifconfig>

site_j-hostname2
<output of ifconfig>

...
site_j-hostnamen
<output of ifconfig>

其中j对应两个站点(取值1或2),目标是生成每行格式为<hostname>,<mac address>的结果。在CentOS 8上编写了如下脚本:

for host in $(grep site_j-hostname filej.txt); do row="$host,"; row+=$(grep -A3 -w $host filej.txt | grep -m1 ether | xargs | cut -d ' ' -f2); echo $row; done

该脚本在Unix LF换行的文件(file命令显示ASCII text)上输出正常,但在Windows CRLF换行的文件(file命令显示ASCII text, with CRLF line terminators)上,仅输出带MAC地址的行,前缀为空:

,xx:xx:xx:xx:xx:xx
,xx:xx:xx:xx:xx:xx
...

原因分析

CRLF换行符包含\r(回车)和\n(换行),当脚本读取带\r的hostname时,$host变量末尾会残留\r字符。后续用grep -w $host匹配时,因为文件中的hostname末尾有\r,而grep -w要求整词匹配,导致无法找到对应行;同时\r会让输出光标回到行首,MAC地址内容覆盖了前缀,最终出现无hostname的结果。

解决方案

方法1:预处理清除回车符

在读取和处理文件时,用tr -d '\r'移除所有\r字符,确保变量和文件内容都统一为LF格式:

for host in $(grep site_j-hostname filej.txt | tr -d '\r'); do
    row="$host,"
    # 处理文件时先清除回车符,再匹配
    mac=$(grep -A3 -w "$host" <(tr -d '\r' < filej.txt) | grep -m1 ether | xargs | cut -d ' ' -f2)
    echo "$row$mac"
done

方法2:精准提取hostname并清理

用grep -o提取纯hostname字符串,再清除可能的\r,避免变量残留控制字符:

# 提取所有site_j-hostname开头的字符串,清除回车符
for host in $(grep -o 'site_j-hostname[0-9]*' filej.txt | tr -d '\r'); do
    row="$host,"
    # 匹配时先清理文件内容的回车符
    mac=$(grep -A3 -w "$host" filej.txt | tr -d '\r' | grep -m1 ether | xargs | cut -d ' ' -f2)
    echo "$row$mac"
done

方法3:用awk高效处理(推荐)

awk原生支持识别LF和CRLF换行,且只需遍历文件一次,逻辑更简洁高效:

awk '
    # 匹配hostname行
    /site_j-hostname/ {
        # 输出上一组的hostname和mac(如果存在)
        if (hostname != "") {
            print hostname "," mac
        }
        # 记录当前hostname并清除回车符
        hostname = $0
        gsub(/\r/, "", hostname)
        mac = ""
    }
    # 匹配ether行,提取第一个MAC地址
    /ether/ && mac == "" {
        for (i=1; i<=NF; i++) {
            if ($i ~ /^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/) {
                mac = $i
                gsub(/\r/, "", mac)
                break
            }
        }
    }
    # 处理最后一组数据
    END {
        if (hostname != "") {
            print hostname "," mac
        }
    }
' filej.txt

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:45:41