#linux #bash
#linux #баш
Вопрос:
Заголовок может быть неоднозначным. Вот пример того, о чем я спрашиваю.
#ls -l
выводит меня что-то вроде этого
-rw-r--r-- 1 root root 5110 2011-10-08 19:36 test.txt
-rw-r--r-- 1 root root 5111 2011-10-08 19:38 test.txt
-rw-r--r-- 1 root root 5121 2011-10-08 19:36 5110.txt
-rw-r--r-- 1 root root 5122 2011-10-08 19:38 5111.txt
Допустим, я хотел использовать grep для поиска всех имен файлов, содержащих '511'
и распечатывающих размер / имя файла.
Как мне использовать grep для имен '511'
файлов, по-прежнему выводить размер файла и не допускать, чтобы выходные данные содержали две верхние строки.
большое вам спасибо, чтение справочных страниц мне в этом не помогло.
Ответ №1:
Вы можете использовать awk
для этого:
pax:~$ echo '
-rw-r--r-- 1 root root 5110 2011-10-08 19:36 test.txt
-rw-r--r-- 1 root root 5111 2011-10-08 19:38 test.txt
-rw-r--r-- 1 root root 5121 2011-10-08 19:36 5110.txt
-rw-r--r-- 1 root root 5122 2011-10-08 19:38 5111.txt
' | awk '{if (substr($8,1,3)=="511"){print $5" "$8}}'
5121 5110.txt
5122 5111.txt
Он просто проверяет поле 8 (имя файла), чтобы увидеть, начинается ли оно с «511», и, если да, выводит поля 5 и 8, размер и имя.
Комментарии:
1. Святая корова. Я пытался использовать awk, но не знал, как выполнить оператор if. Очень полезная информация. Спасибо!
2. Это работает некорректно для файлов с пробелами в их имени. Это не так сложно исправить.
3. Кроме того, substr ищет совпадения только в начале имени файла, а не где-либо в имени. Опять же, это не так сложно исправить, но
ls
следует избегать синтаксического анализа выходных данных.4. Более простое решение:
awk '$8 ~ /.*511.*/ {print $5" "$8}'
5. uzsolt. Как это называется? Как я могу получить больше информации об этом синтаксисе и что все это значит.
Ответ №2:
find . -name '*511*' -printf "%st%pn"
Комментарии:
1. Возможно, добавить
-maxdepth 0
, чтобы предотвратитьfind
попадание в подкаталоги.
Ответ №3:
Если вы хотите отфильтровать только имя файла, почему вы в первую очередь перечисляете другие файлы?
ls -l *511* | cut -c23-30,48-
или даже с awk
;
ls -l *511* | awk '{ $1 = $2 = $3 = $4 = $6 = $7 = ""; print }'
Однако выходные данные ls
не являются полностью надежными, поэтому вам следует избегать их прямой обработки.
perl -le 'for (@ARGV) { print ((stat($_))[7], " $_") }' *511*
stat()
Системный вызов возвращает необработанную информацию, отображаемую ls
в машиночитаемом формате. Любой инструмент, который дает вам доступ к этой информации, подойдет; он не обязательно должен быть Perl.
Ответ №4:
Вы можете обойти ls
и просто использовать bash
имя файла glob
:
for f in 511*
do
echo $f $(stat --format '%s' $f)
done