Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: bash, логическая ошибка в цикле for подсчета строк в файлах  (Прочитано 66659 раз)

0 Пользователей и 1 Гость просматривают эту тему.

krdgroup

  • Автор темы
  • Гость
Написал скрипт подсчета строк в файлах. Сами файлы могут храниться в разных каталогах, но все в дочерних файла скрипта. В зависимости от текущей даты надо брать файлы из каталога с названием текущего месяца или предыдущего ( к примеру 2211 или 2210 ). Получается скрипт не воспринимает файл как файл. Т.е. к примеру в скрипте ниже находит 2 пути к 2 файлам
./AXE/CNA5/LBN/2211:
test3.txt
./AXE/TELLIN/2211:
test4.txt
и просто выводит на экран
cat: './AXE/CNA5/LBN/2211:': No such file or directory
0
cat: test3.txt: No such file or directory
0
cat: './AXE/TELLIN/2211:': No such file or directory
0
cat: test4.txt: No such file or directory
0
А должен считать кол-во строк в файлах
./AXE/CNA5/LBN/2211:
15
12
./AXE/TELLIN/2211:
7
Сам скрипт
#!/bin/bash
#заносим в переменную текущее число месяца
timestamp=$(date +%d)
#если сейчас 1 число то присваиваем переменной предыдущий месяц, иначе текущий
if [[ $timestamp == 1 ]]; then
folder=$(date -d " - $(date +%d) days" +%y%m)
else
folder=$(date +%y%m)
fi
#находим путь к файлам
path=$(find ./ -type d -name "$folder")
#находим файлы
for file in  $(ls $path)
do
echo $(cat $file | wc -l)
done
Что мне нужно исправить чтобы получить нужный результат?
« Последнее редактирование: 24 Ноября 2022, 17:07:18 от krdgroup »

Оффлайн ALiEN175

  • Администратор
  • Старожил
  • *
  • Сообщений: 5758
  • Vamos a Bailar
    • Просмотр профиля
timestamp=$(date +%d)
01 не будет равен 1
timestamp=$(date +%-d)
for file in  $(ls $path)
do
   echo $(cat $file | wc -l)
done
for file in $path/*
do
wc -l $file
done

или вообще без цикла
find ./ -type d -name "$folder" -exec grep -Rc ".*" {} \; # включая пустые строки
find ./ -type d -name "$folder" -exec grep -Rc . {} \; # без пустых строк
« Последнее редактирование: 24 Ноября 2022, 20:19:06 от ALiEN175 »
ASUS P5K-C :: Intel Xeon E5450 @ 3.00GHz :: 8 GB DDR2 :: Radeon R7 260X :: XFCE
ACER 5750G :: Intel Core i5-2450M @ 2.50GHz :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

krdgroup

  • Автор темы
  • Гость
for file in $path/*
do
   wc -l $file
done

А из-за чего может не во всех папках считать? Я такой скрипт пишу
#!/bin/bash
#заносим в переменную текущее число месяца
timestamp=$(date +%d)
#если сейчас 1 число то присваиваем переменной предыдущий месяц, иначе текущий
if [[ $timestamp == 01 ]]; then
folder=$(date -d " - $(date +%d) days" +%y%m)
else
folder=$(date +%y%m)
fi
#находим путь к файлам
path=$(find ./ -type d -name "$folder")
#находим файлы и считааем кол-во записей
for file in $path/*
do
wc -l $file
done

Он выдает результат:
wc: ./AXE/CNA5/LBN/2211: Is a directory
0 ./AXE/CNA5/LBN/2211
16 ./AXE/TELLIN/2211/1.txt
Хотя по пути ./AXE/CNA5/LBN/2211 тоже лежит файл 2.txt с двумя записями. Причем если в 3-ю директорию размещаю файл тоже только в одной считает. 
wc: ./AXE/CNA5/LBN/2211: Is a directory
0 ./AXE/CNA5/LBN/2211
wc: ./AXE/RYBIN/2211: Is a directory
0 ./AXE/RYBIN/2211
16 ./AXE/TELLIN/2211/1.txt
Может из-за того что в git bash работаю и тут что то типо $(wc -l $file) надо писать, но так все равно не работает.

И как еще можно цикл изменить чтобы он с форматом .z работал. А то так не работает:
for file in $path/*
do
zcat $file | wc –l
done
И чтобы сумму всех строк во всех файлах в одной директории считал. В таком духе:
16  ./AXE/CNA5/LBN/2211
32  ./AXE/TELLIN/2211
Ну или как через find это сделать

Оффлайн andytux

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5905
    • Просмотр профиля
Цитировать
Я такой скрипт пишу...
Не обращай внимание, я не по теме.
С первой строки, bash уже давно не в /bin. Да и самого каталога /bin уже нет. Пока еще есть символическая ссылка...

Цитировать
#если сейчас 1 число то присваиваем переменной
Но вот первого числа компьютер не включали, а сегодня второе...

krdgroup

  • Автор темы
  • Гость
С первой строки, bash уже давно не в /bin. Да и самого каталога /bin уже нет. Пока еще есть символическая ссылка...

Получается вместо #!/bin/bash что то написать другое надо? Что тогда?

Компьютер всегда включен

Оффлайн andytux

  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 5905
    • Просмотр профиля
"Лучше один раз увидеть..."
Рядом тебе верно посоветовали (проговорить или записать: «берётся … ), но это нужно быть хорошим шахматистом, чтобы "видеть всю доску".
Уж давно придумали "отладочные сообщения". Что-нибудь типа:
...
for file in $path/*
do
echo "$version.$ex.$(basename "$0").dbg1: $path [$file]"
wc -l $file
done

...
У меня сложился такой шаблон для них:
version, ex - переменные, которые используются во многих моих скриптах, у тебя вместо них будет пусто
basename - выведет имя скрипта, бывает полезно, если скрипт вызван в другом скрипте
dbg1 - метка сообщения, чтобы знать, какому конкретно месту кода соответствует это сообшение
Дальше собственно то, что ты хотел-бы видеть в этом сообщении.

Цитировать
Компьютер всегда включен
Когда-то тоже подумали столь недальновидно и обозначили год двумя цифрами. Уже больше двадцити лет "проблеме 2000" и до сих пор отрыгается.

 

Страница сгенерирована за 0.022 секунд. Запросов: 21.