我在cygwin上使用bash。
我必须获取一个.csv文件,该文件是一组更大的设置的子集,并将新的csv设置(相同的键,不同的值)混合到1000多行的原始文件中,制作一个新的.json文件。
我已经整理了一个脚本来自动执行此操作。该过程的第一步是通过提取以“mme”和“sms”开头的行来“清理”csv文件。其他一切都是干净利落地通过“干净”.csv文件。
此例程如下:
# clean up the settings, throwing out mme and sms entries
cat extract.csv | while read -r LINE; do
if [[ $LINE == "mme "* ]]
then
printf "$LINE\n" >> mme_settings.csv
elif [[ $LINE == "sms "* ]]
then
printf "$LINE\n" >> sms_settings.csv
else
printf "$LINE\n" >> extract_clean.csv
fi
done
我的问题是,这个东西在一个条目末尾的下面的字符串上固定它的脚趾: 100%."
当它完成该行时,它只是忽略了%."
和新行标记跟着它,将两条线涂抹在一起:
... 100next.entry.keyname...
我很想进入并简单地手动界定%
符号,但这对我的用例来说不是一个现实的选择。显然我错过了一些东西。我的怀疑是,我在第一行有些明智地滥用cat
或read
。
如果有一些地方,我应该在找到答案之前找到答案,无论如何都要指向我那个方向然后我会离开。
答案 0 :(得分:4)
printf
的语法是:
printf format [argument]...
在[ printf ]格式字符串中,后跟%
的任何内容都是格式说明符,如上面的链接所述。你想做的是:
while read -r line; do # Replaced LINE with line, full uppercase variable are reserved for the syste,
if [[ "$line" = "mme "* ]] # Here* would glob for anything that comes next
then
printf "%s\n" $line >> mme_settings.csv
elif [[ "$line" = "sms "* ]]
then
printf "%s\n" $line >> sms_settings.csv
else
printf "%s\n" $line >> extract_clean.csv
fi
done<extract.csv # Avoided the useless use of cat
答案 1 :(得分:3)
正如所指出的,您的问题是在printf
的格式化参数中扩展包含格式化指令的参数,这可以通过使用echo
代替或移动参数来扩展出来。格式化字符串,如其他答案所示。
我建议不要首先使用Bash循环遍历整个文件,因为它的速度非常慢;你从某些模式开始提取行,这是grep擅长的工作:
grep '^mme ' extract.csv > mme_settings.csv
grep '^sms ' extract.csv > sms_settings.csv
grep -v '^mme \|^sms ' extract.csv > extract_clean.csv
第三个命令使用-v
选项(提取不匹配的行)和替换以排除以mme
和{{1}开头的行}。