如果问题很简单,很抱歉。我是一个在shell脚本编程的初学者,我需要写一个脚本,将工作在mksh安装的机器上的文本文件,但没有工作版本的sed或大多数gnu实用程序或兼容。
也没有安装dos2unix的版本。
该脚本接收dos格式的文件,但其包含的字符种类非常简单(仅字母和数字,每行的长度不超过20个字符,少于1000行),它会逐个字符读取文件,并将字符添加到" line“变量。当它到达回车符时,它会打印该行。用法为sh script.sh file.txt > newfile.txt。
脚本没有像预期的那样工作,我不是很确定原因:
#!/bin/sh
riga="";
nomefile="$1";
while IFS='' read -r -n1 carattere;
do
if [[ $carattere != *$'\r'* ]]; then
riga="${riga}carattere";
elif [[ $carattere == *$'\r'* ]]; then
print "${riga%$}";
riga="";
fi
done < "$nomefile"这是最初编写的脚本的输出:
caratterecaratterecaratterecaratterecaratterecaratterecaratterecaratterecarattere
caratterecaratterecaratterecaratterecaratterecaratterecaratterecaratterecarattere
caratterecaratterecaratterecaratterecaratterecaratterecaratterecaratterecarattere
caratterecaratterecaratterecaratterecaratterecaratterecaratterecaratterecarattere
caratterecaratterecaratterecaratterecaratterecaratterecaratterecaratterecarattere
caratterecaratterecaratterecaratterecaratterecaratterecaratterecaratterecarattere
caratterecaratterecaratterecaratterecaratterecaratterecaratterecaratterecarattere
caratterecaratterecaratterecaratterecaratterecaratterecaratterecaratterecarattere
caratterecaratterecaratterecaratterecaratterecaratterecaratterecaratterecarattere我在https://www.freebsd.org/cgi/man.cgi?query=ksh上阅读了ksh的优秀手册页,并修改了脚本,如下所示:
#!/bin/sh
#!i=0
#!
riga="";
nomefile="$1";
while IFS='' read -r -n1 carattere;
do
if [[ $carattere != *$'\r'* ]]; then
riga="${riga}$carattere";
elif [[ $carattere == *$'\r'* ]]; then
print "${riga%$}";
riga="";
fi
done < "$nomefile"输出与我想要的类似,但是在打印行之间插入了空行:
ID
1
2
3
4
5
6
7
8发布于 2018-01-10 01:24:19
好的,在进一步阅读了ksh手册页和一些测试之后,我发现了哪里出了问题。我的脚本的第一个版本没有正确地将我读取的字符附加到riga变量,因为我没有使用替换($)来附加carattere变量。
第二个版本按预期工作,但没有考虑到dos文件以CRLF结束行的事实:我因此检查\r字符,这意味着\n字符被添加到我的riga变量中。我修改了第一个if条件,以检查字符是否也与\n不同。
然后,我的脚本中的另一个问题是,在我想要转换的文件结构中,有n行,最后一行没有终止。这意味着我的脚本不会在riga变量中写入最后一行的字符,但不会打印最后一行。我解决了这个问题,在while循环之后添加了一个打印指令,使用-n参数来避免在字符串之后打印换行符。
脚本的最终版本是:
#!/bin/sh
#!i=0
#!^M
riga="";
nomefile="$1";
while IFS='' read -r -n1 carattere;
do
if [[ $carattere != *$'\r'* ]] && [[ $carattere != *$'\n'* ]]; then
riga="${riga}$carattere";
elif [[ $carattere == *$'\r'* ]]; then
print "${riga%$}";
riga="";
fi
done < "$nomefile"
print -n "${riga%$}";感谢本杰明,他的评论让我找到了解决问题的正确方向。
https://stackoverflow.com/questions/48165517
复制相似问题