Shell脚本中文件名末尾出现不需要的“?”字符

13
在执行这个操作时,我的文件名末尾会出现一个不想要的“?”符号:
emplid=$(grep -a "Student ID" "$i".txt  | sed 's/(Student ID:  //g' | sed 's/)Tj//g' ) 
 #gets emplid by doing a grep from some text file
echo "$emplid"   #prints employee id correctly 
cp "$i" "$emplid".pdf  #getting an extra '?' character after emplid and before .pdf

即,我得到的文件名不是123456.pdf,而是123456?.pdf。 如果echo打印正确,为什么会出现这种情况? 如何删除后面的问号字符?


你使用了 cp "$i" "$emplid".pdf,但在 "$i" 上没有 .txt,文件是否被正确复制?如果是,请尝试在 cp 行中删除 $i$emplid 周围的引号。 - sampson-chen
1
执行命令 echo "$emplid>xxx.txt",然后使用例如 od -c xxx.txt 命令检查文件内容,查看末尾的内容。 - pbhd
@sampson-chen:我尝试了cp $i.txt $emplid.pdf,cp“$i”.txt“$emplid”.pdf。都不行。 - premprakash
@pbhd:我得到了这个0000000 0 0 0 0 1 5 8 5 7 \r \n 0000013。 - premprakash
嗯。那么Gordon的回答适用。你需要使用dos2unix重新格式化文件以摆脱cr lf序列(在这里看到为\r(\n来自echo命令)),或者作为快速hack,执行sed 's/.$//'以摆脱行末的最后几个字符。甚至可以使用sed 's/\r$//',但不确定是否是在sed内指定cr的正确语法。 - pbhd
@pbhd:sed 's/.$//' 已经生效。谢谢。 - premprakash
2个回答

14

看起来你的脚本文件具有DOS风格的行结尾符(\r\n)而不是Unix风格(只是\n)-- 在此格式的脚本中,\r会被视为命令的一部分。在这种情况下,它被包含在$emplid中,因此也包含在文件名中。

许多平台支持dos2unix命令将文件转换为Unix风格的行结尾符。一旦转换完成,请使用支持Unix风格文本文件的文本编辑器。

编辑:我曾假设问题行结束符在shell脚本中,但看起来实际上在输入文件("$i".txt)中。您可以对输入文件使用dos2unix进行清理,或在脚本中的sed命令中添加清理步骤。顺便说一下,您可以使用-e选项使单个sed实例应用多个编辑:

emplid=$(grep -a "Student ID" "$i".txt  | sed '-e s/(Student ID:  //g' -e 's/)Tj//g' -e $'s/\r$//' )

我建议不要使用sed 's/.$//' -- 如果文件是UNIX格式,那么会剪切掉文件名的最后一个字符。


是的,我想你说得对。我按照pbhd提到的方法做了,现在看到的是0000000 0 0 0 0 1 5 8 5 7\r\n 0000013 。我该如何去掉\r,以使我的cp命令正常工作? - premprakash
在执行cp命令后,我使用了dos2unix -k "$emplid".pdf,但它没有起作用。有什么建议吗? - premprakash
不,你必须清理输入文件,即你正在使用grep搜索学生ID的那个文件,因为它会在末尾给你垃圾字符。 - pbhd
1
在这一行中:###emplid=$(grep -a "学生ID" "$i".txt | sed 's/(学生ID: //g' | sed 's/)Tj//g')###,你正在读取一个名为 $i.txt 的文件。该文件需要使用 dos2unix 进行清理/转换。 - pbhd
我正在测试fgets()在保留stdin流中的文本时的工作方式。它使用流中剩余的内容创建了一个文件,并在文件扩展名的末尾附加了一个问号。 - Ungeheuer
显示剩余3条评论

0
使用file命令检测文件是否为纯Unix文件或混合DOS文件。
DOS文件:ASCII文本,带有CRLF行终止符 Unix文件是纯ASCII文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接