在行之前的某个地方count=~echo "$conflict" | wc -l~
(~ 代替反引号),0x0A
添加了十六进制字符。因此,当文件$DA
和$DB
相同时(意味着脚本应返回一个空集),0x0A
将添加。因此,下一个命令中的行数不是零,而是 1。它被添加到循环每次迭代的输出末尾。对于返回其他内容的循环来说,这不是什么大问题,但对于应该返回空集的循环来说,这很烦人(因此,不应创建新文件)。我尝试在行的开头和结尾插入tr -d '\r'
和,但没有帮助。tr -d '\n'
conflict=~cat "$DA" "$DB"
我怎样才能简单地删除仅包含此字符(或实际上除 之外的任何不可打印字符\n
)的任何行?
非常感谢您的帮助。
# Files "DA" and "DB" are titled as such:
# 10M_$i_$j_$m_OtherNonRelevantChars or 10M_$i_$k_$n_OtherNonRelevantChars
# Field one is an integer; fields 2 and 3 are alphanumeric (checksum hashes)
IFS=$'\n'
for i in {1..7}
do for j in {P,B,R}
do for k in {P,B,R}
do for m in {3,9}
do for n in {3,9}
do
DA=`ls "10M_${i}_${j}_${m}"*`
DB=`ls "10M_${i}_${k}_${n}"*`
dos2unix "$DA" "$DB"
conflict=`cat "$DA" "$DB" | \
awk -v OFS=',' -F',' '{print $1,substr($2,0,8),substr($3,0,8)}' | \
sort -t',' -k1,1n | uniq -u | \
awk -v i=$i -v j=$j -v k=$k -v m=$m -v n=$n -v OFS=',' -F',' '{print i,j,m,k,n,$1}' | \
uniq -d`
# The unwanted character appears somewhere before here
count=`echo "$conflict" | wc -l`
if [[ "$count" -gt 0 ]]
then
echo $conflict >> "C_${i}_${j}_${m}_${k}_${n}.txt" # output of conflicting hashes for given matching unique first field ID
fi
echo "$i $j $m $k $n"
done
done
done
done
done
答案1
$count
总是大于零,因为echo
添加换行符。以下每个命令都会打印1
:
conflict=""; echo "$conflict" | wc -l
echo "" | wc -l
echo | wc -l
回显包含换行符的变量的内容只能增加计数。
事情是这样的:
因此我们可以考虑几种情况:
如前所述,
echo
只添加一个换行符。
因此,在echo
至少有一个换行符之后,并且[[ "$count" -gt 0 ]]
始终为真。更糟糕的是,使用printf
或echo -n
来避免添加额外的换行符(将其与考虑在内-gt 1
)并不是一个解决方案,因为“恰好一行”和“空输出”(以及少数其他情况)在变量中生成相同数量的换行符:零。
在你的情况下大概测试一下是否$conflict
不为空就足够了:
[ -n "$conflict" ]
一般来说,你可能想要继续使用换行符。不过看来你的第二个awk
不能生成空行。
注意如果你count
直接计算,没有中间conflict
变量
count="$(cat … | … | wc -l)"
那么就没有问题了。我注意到你$conflict
稍后使用(你不想引用它吗?),因此这种方法实际上不是一个选择(除非您决定独立获取count
和conflict
,但这不是最优的,并且一般来说,当输入数据在其间发生变化时可能会导致不一致的结果)。
让我们回到不完整的行。您正在使用dos2unix
。在 DOS/Windows 世界中,文本文件可能以不完整的行结尾(例如POSIX 术语)。如果发生这种情况,dos2unix
则不完整的行之后仍将不完整。运行时至少有两个潜在问题cat "$DA" "$DB" | …
:
- 如果第一个文件以不完整的行结束,那么它将与第二个文件的开头连接起来,中间没有任何换行符。
- 如果第二个文件以不完整的行结尾,则输出
cat
将以此行结束,管道中稍后的工具可能会“行为不当”。文本处理工具期望文本,线。一般来说,当遇到不完整的线时,此类工具可能会:- 忽略不完整的线,就好像它不存在一样;
- 或者接受它并将它(想象一个类似的过滤器
grep
)作为不完整的行传递到它的输出; - 或者接受它,修复(添加换行符)并将其作为完整的行传递给其输出;
- 或抛出错误(例子)。
因此请注意您的输入文件。