Новый вопрос в 22.9.2016, ниже!
Мой путь выглядит следующим образом:
~/Desktop/logs
├── first_folder
| ├── 11.11 (folder)
│ | ├── access_log
│ | ├── access_log.1.gz
│ | :
│ | └── access_log.40.gz
| └── 11.12 (folder)
│ ├── access_log
│ ├── access_log.1.gz
│ :
│ └── access_log.16.gz
├── second_folder (folder)
| ├── 31.11 (folder)
│ | ├── access_log
│ | ├── access_log.1.gz
│ | :
│ | └── access_log.20.gz
| └── 31.15 (folder)
│ ├── access_log
│ ├── access_log.1.gz
│ :
: └── access_log.38.gz
└── last_folder
├── 91.11 (folder)
| ├── access_log
| ├── access_log.1.gz
| :
| └── access_log.25.gz
└── 91.15 (folder)
├── access_log
├── access_log.1.gz
:
└── access_log.30.gz
Из всех журналов мне нужно извлечь данные, содержащие строку: /Jan/2016
Как я могу получить все записи из всех файлов во всех папках и сохранить их как single_file.txt
Вывод:
single_file.txt
./first_folder/11.11/access_log.9.gz: ... text ...
./first_folder/11.12/access_log.9.gz: ... text ...
./second_folder/31.11/access_log.9.gz: ... text ...
./second_folder/31.11/access_log.9.gz: ... text ...
:
Как я могу получить все записи из всех файлов во всех папках и сохранять их отдельно в зависимости от записей, которые я захватываю из first_folder, second_folder и т. Д., Например first.txt, second.txt.
Результат будет выглядеть примерно так:
first.txt
./first_folder/11.11/access_log.9.gz: ... text ...
./first_folder/11.12/access_log.9.gz: ... text ...
:
second.txt
./second_folder/31.11/access_log.9.gz: ... text ...
./second_folder/31.15/access_log.9.gz: ... text ...
:
Как я могу получить список всех файлов, содержащих строку /Jan/2016?
Если я использую эту команду, он будет извлекать все файлы:
$ find ~/Desktop/logs/ -type f | xargs zgrep -l "/Jan/2016"
Выход:
Terminal
/home/name/Desktop/logs/first_folder/11.11/access_log.9.gz
/home/name/Desktop/logs/first_folder/11.12/access_log.8.gz
/home/name/Desktop/logs/second_folder/31.11/access_log.6.gz
:
@ код waltinator-s и @ коррекция Zanna:
pushd ~/Desktop/logs
for dir in * ; do
if [[ -d "$dir" ]] ; then
outname="$dir.txt"
find "$dir" -type f -print0 | xargs -0 zgrep -l '/Jan/2016' >"$outname"
fi
done
popd
даст мне структуру:
~/Desktop/logs
├── first_folder
| └── first.txt
├── second_folder
| └── second.txt
:
└── last_folder
└── last.txt
где first.txt-last.txt будет содержать пути к конкретным файлам, которые содержат строку /Jan/2016.
first.txt
first_folder/11.11/access_log.9.gz
first_folder/11.11/access_log.8.gz
first_folder/11.12/access_log.9.gz
first_folder/11.12/access_log.8.gz
Мне нужно было изменить /Jan/2016 на определенный период time ... например 1/Nov/2014-31/Apr/2015, поэтому в коде, который @Zana предоставил вместо /Jan/2016, я использовал /(Nov|Dec)/2014|/(Jan|Feb|Mar|Apr)/2015. Предупреждение:
xargs: Warning: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the --null option?
Все результаты не возвращаются в созданных файлах, хотя все файлы создаются.
Современный способ использования find, имея в виду, что вы в конце концов увидите имя файла, содержащее пробелы, находится с -print0 и xargs -0:
# list all filenames containing '/Jan/2016'
find ~/Desktop/logs -type f -print0 | xargs -0 zgrep -l '/Jan/2016'
# 1. Have all the data from all folders that contain that string under one text file
find ~/Desktop/logs -type f -print0 | xargs -0 zgrep -l '/Jan/2016' >one.text.file
#
# 2. Have data that contains string in a separate text files depending on a folder (example: first folder - first.txt etc)
pushd ~/Desktop/logs
for dir in * ; do
if [[ -d "$dir" ]] ; then
outname="$dir.txt"
find "~/Desktop/logs/$dir" -type f -print0 | xargs -0 zgrep -l '/Jan/2016' >"$outname"
fi
done
popd