Ubuntu (14 и 16) Ошибки Bash с циклами printf из ввода, содержащего строчные буквы "n"
У меня есть несколько скриптов bash, которые я запускаю в Ubuntu 14.04 и 16.04 уже более года. Некоторое недавнее обновление Ubuntu сломало bash, и я не могу понять, как с этим разобраться.
Пример:
#!/bin/bash
INPUT=myinput.txt
OUTPUT=myoutput.txt
ACTION1="0;"
cat $INPUT | while read LINE
do
printf "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
done
мой скрипт затем перебирает файл, выполняя оператор printf следующим образом, но это вывод
"~jetmo" 0;
"~spamme" 0;
"~baidu" 0;
пример содержимого файла myinput.txt
jetmon
spammen
baidu
Строки ввода, содержащие строчные буквы n, удаляются?? Я пропустил некоторые серьезные изменения в bash, которые произошли, это начало происходить неделю назад и сводит меня с ума сейчас.
Я попытался изменить #!/ Bin/bash на #!/ Bin/sh с теми же результатами.
Также пробовал этот метод зацикливания во входном файле и по-прежнему получать те же результаты.
#!/bin/bash
INPUT=myinput.txt
OUTPUT=myoutput.txt
ACTION1="0;"
while read LINE
do
printf "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
done < $INPUT
Попробовал предложение из комментариев с помощью эха
echo -e -n "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
и теперь я получаю этот вывод
-e -n "~jetmo" 0;
-e -n "~spamme" 0;
-e -n "~baidu" 0;
Запуск hexdump -C myinput.txt дает этот вывод
00000000 6a 65 74 6d 6f 6e 0a 73 70 61 6d 6d 65 6e 0a 62 |jetmon.spammen.b|
00000010 61 69 64 75 0a 0a |aidu..|
00000016
Также изменил имена всех переменных в нижний регистр, как было предложено Майклом, но все равно получил те же результаты.
#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
cat $input | while read line
do
printf "\t\"~${line}\"\t\t$action1\n" >> $output
done
РЕШЕНИЕТайна разгадана
спасибо всем, но l0b0 прибил его по голове. У меня был IFS=$'\n'
ранее скрывался в моем сценарии.
Теперь у меня есть последнее, лучшее и безопасное форматирование printf благодаря рекомендациям Науэля и Чарльза, и оно работает на 100% ... не могу вас всех отблагодарить.
#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
while IFS= read -r LINE
do
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$output"
done < $input1
3 ответа
Это может произойти, если внутренний разделитель полей ($IFS
) содержит письмо n
:
$ IFS=$' \t\nn' read line <<< foon
$ printf '%q\n' "$line"
foo
Это довольно распространенная ошибка. Вот правильное значение:
$ printf '%q\n' "$IFS"
$' \t\n'
Пример:
$ IFS=$' \t\n' read line <<< foon
$ printf '%q\n' "$line"
foon
Безопаснее использовать %s
вставить строку с помощью printf, например, если она может содержать %
printf "\t\"~%s\"\t\t%s\n" "${LINE}" "$ACTION1" >> $OUTPUT
РЕДАКТИРОВАТЬ следующие комментарии, с одинарными кавычками в первом аргументе, потому что нет расширения переменной
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$OUTPUT"
РЕШЕНИЕТайна разгадана
спасибо всем, но l0b0 прибил его по голове. У меня был IFS=$'\n'
ранее скрывался в моем сценарии.
Теперь у меня есть последнее, лучшее и безопасное форматирование printf благодаря рекомендациям Науэля и Чарльза, и оно работает на 100% ... не могу вас всех отблагодарить.
#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
while IFS= read -r LINE
do
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$output"
done < $input1