Чтение в файле построчно с Bash
Лучший идиоматический способ читать файл построчно:
while IFS= read -r line; do
// parse line
printf "%s" "$line"
done < "file"
Больше на эту тему можно найти на bashfaq
Однако не читайте файлы в bash построчно. Вы можете (хорошо, почти) всегда не читать поток построчно в bash. Строковое чтение файла в bash чрезвычайно медленное и не должно выполняться. Для простых случаев можно использовать все инструменты Unix с помощью xargs
или parallel
, для более сложных awk
и datamesh
.
done < "directoryoutput"
Код не работает, потому что вы передаете свой цикл while в качестве входных данных для стандартного ввода содержимого файла с именем directoryoutput
. Так как такого файла не существует, ваш скрипт завершается ошибкой.
directoryoutput=$(find -name $outputfilename)
Можно просто добавить значение переменной с добавленной новой строкой к циклу чтения, используя конструкцию HERE-string:
done <<< "$directoryoutput"
directoryinput=$(find -name $inputfilename)
if [[ -f "$directoryinput" ]]
Это нормально, если в вашем каталоге есть только один файл с именем $inputfilename
. Также нет смысла искать файл, а затем проверять его наличие. В случае большего количества файлов find возвращает список имен, разделенных новой строкой. Однако небольшой чек if [ "$(printf "$directoryinput" | wc -l)" -eq 1 ]
или использование find -name $inputfilename | head -n1
я думаю, будет лучше.
while read line;
do
echo "$line"
n=$((n+1))
done < "directoryoutput"
Намерение здесь довольно ясно. Это просто:
n=$(<directoryoutput wc -l)
cat "directoryoutput"
За исключением того, что while read line
убрал завершающие и ведущие символы новой строки и зависит от IFS.
Также всегда не забывайте указывать в кавычках ваши переменные, если у вас нет причин не делать этого.
Взгляните на shellcheck , который может найти наиболее распространенные ошибки в скриптах.
Я бы сделал это примерно так:
inputfilename="employees.txt"
outputfilename="branch.txt"
directoryinput=$(find . -name "$inputfilename")
directoryinput_cnt=$(printf "%s\n" "$directoryinput" | wc -l)
if [ "$directoryinput_cnt" -eq 0 ]; then
echo "Input file does not exist. Please create a '$inputfilename' file" >&2
exit 1
elif [ "$directoryinput_cnt" -gt 1 ]; then
echo "Multiple file named '$inputfilename' exists in the current path" >&2
exit 1
fi
directoryoutput=$(find . -name "$outputfilename")
directoryoutput_cnt=$(printf "%s\n" "$directoryoutput" | wc -l)
if [ "$directoryoutput_cnt" -eq 0 ]; then
echo "Input file does not exist. Please create a '$outputfilename' file" >&2
exit 1
elif [ "$directoryoutput_cnt" -gt 1 ]; then
echo "Multiple file named '$outputfilename' exists in the current path" >&2
exit 1
fi
cat "$directoryoutput"
n=$(<"$directoryoutput" wc -l)