У меня есть набор отдельных файлов basename.file
, в нескольких каталогах basename_dir
. Я хочу скопировать все файлы .file
в один каталог. Я создал .txt
, содержащий все базовые имена. Я хочу использовать цикл for, чтобы сделать это, но продолжаю получать ошибку
Это то, что я использую:ehsant @ lp02944 : ~ / test $ ll всего 24 drwxr-xr-x 2 ehsant ehsant 4096 19 мая 17:54. drwxr-xr-x 6 Ehsant Ehsant 4096 19 мая 14:45 .. -rw-r - r-- 1 ehsant ehsant ...
Если у меня есть эти файлы в моей папке test
ehsant@lp02944:~/test$ll
total 24
drwxr-xr-x 2 ehsant ehsant 4096 May 19 17:54 .
drwxr-xr-x 6 ehsant ehsant 4096 May 19 14:45 ..
-rw-r--r-- 1 ehsant ehsant 7 May 19 14:53 log.20200519_04
-rw-r--r-- 1 ehsant ehsant 7 May 19 14:54 log.20200519_05
-rw-r--r-- 1 ehsant ehsant 8 May 19 14:55 log.20200519_06
-rw-r--r-- 1 ehsant ehsant 7 May 19 14:56 log.20200519_07
Предположим, текущая дата 2020/05/19
Как можно Я ищу определенное слово в самом последнем файле, который является log.20200519_07
Мое требование ограничивает меня иметь команду bash только в 1 строке.
Сначала я должен проверить наличие файлов с этим форматом log. $ (Дата +% Y% m% d) _ ??
и если я нашел что-нибудь, поиск в самом последнем.
Существуют разные сценарии:
1- В папке нет файла -> Тогда ничего не делать
2- В папке только один файл -> Затем выполните поиск в этом отдельном файле
3- В папке более 1 файла -> Затем найдите самый последний файл и выполните поиск внутри этого файла.
Пока у меня есть эта команда:
if [ -e ~/test/log.$(date +%Y%m%d)_?? ]; then ls -tr1 ~/test/log.$(date +%Y%m%d)_?? | tail -1 | xargs grep -q "WARNING"; else exit 123; fi
Эта команда работает для первого и второго сценария, но не для третьего.
Если происходит сценарий 3, я получаю ошибку bash: [: too many arguments
, а затем она попадает в предложение else
Есть идеи, почему это происходит?
Я бы вместо этого использовал цикл ls
version sort:
$ for i in $(ls -r1v ~/test/log.* 2>/dev/null); do \
grep -q "WARNING" < "$i" && echo match; break; done
Другой пример использования read :
$ read -r < <(ls -r1v ~/test/log.* 2>/dev/null) && \
{ grep -q "WARNING" < "$REPLY" && echo match; } || echo file not found.
В сценарии я предпочитаю проверять существование перед использованием файла.
#!/bin/bash
mapfile -t -n 1 < <(ls -r1v ~/test/log.* 2>/dev/null)
[[ -e $MAPFILE ]] || \
{ echo file not found.; exit 123; }
grep -q "WARNING" < "$MAPFILE" && echo match || echo no match
Спасибо за вашу помощь, ребята,
Я нашел ваш ответ с вашей помощью.
Эта команда сработала для меня:
if [ "$(ls -1 ~/test/log.$(date +%Y%m%d)_?? 2>/dev/null | wc -l)" -gt 0 ]; then ls -tr1 ~/test/log.$(date +%Y%m%d)_?? | tail -1 | xargs grep -q "WARNING"; else exit 123; fi
Итак, я проверяю, больше ли число файлов, чем 0, затем нахожу самый последний и внутри него grep.
И 2> / dev / null
помог мне bypass Ошибка такого файла или каталога
, если в папке нет файла. Вы можете обратиться к этому комментарию https://stackoverflow.com/a/40714363/1908331 для этого