С awk
:
awk -F/ '$1=="<<" {i=$2; for(j=3;j<=NF;j++) \
if($j~/^Contents/) split($j,a,"[()]"); print i " _ " a[2]}' file.txt
Установка разделителя полей как /
, если первое поле ] <<
, затем сохранение второго поля как переменной i
для печати позже
Итерация по остальным полям, и если какое-либо поле начинается с Contents
, то разделение поля на ()
для создания массива a
, для (j = 3; j <= NF; j ++) if ($ j ~ / ^ Contents /) split ($ j, a, "[()]")
выводит переменную i
и второй элемент массива a
, разделяя их _
Пример:
% cat file.txt
1731 0 obj
<</Page 250/Type/Annot/Subtype/Highlight/Rotate 0/Rect[ 95.4715 347.644 337.068 362.041]/NM(929cd95c-f962-4fa3-b734-2e0e67d7b321)/T(iPad)/CreationDate(D:20160818145053Z00'00')/M(D:20160818145204Z00'00')/C[ 0.454902 0.501961 0.988235]/CA 1/QuadPoints[ 95.4715 362.041 337.068 362.041 95.4715 347.644 337.068 347.644]/Contents(EXAMPLE OF TEXT TO BE EXTRACTED)/F 4/Subj(Highlight)>>
endobj
% awk -F/ '$1=="<<" {i=$2; for(j=3;j<=NF;j++) if($j~/^Contents/) split($j,a,"[()]"); print i " _ " a[2]}' file.txt
Page 250 _ EXAMPLE OF TEXT TO BE EXTRACTED
#!/bin/bash
OLD_IFS=${IFS}
IFS=:
for folder in $PATH
do
cd ${folder}
echo "Inside the folder ${folder}"
for file in *
do
if [ -x ${file} ]
then
echo "${file} is executable"
else
echo "${file} is not executable"
fi
done
done
IFS=${OLD_IFS}
С одной стороны, $ PATH
дает список каталогов. Если вы хотите проверить каждый файл в $ PATH
, вам нужно будет просмотреть каждый файл в каждом каталоге, а не просто проверять каждый элемент в $ PATH
.
Затем вы используете -x
, чтобы проверить, является ли файл исполняемым, но вы не указываете, какой файл проверять. Я написал исправленную версию ниже:
IFS=':'
for directory in $PATH; do
for file in $directory/*; do
if [ -x $file ]; then
echo "Executable File: " $file
else
echo "Not executable: " $file
fi
done
done
Ответ Фокса - гораздо более хорошее решение, но я просто подумал, что вам будет интересно узнать, что не так с вашим.
Если вам нужен список исполняемых файлов, find
будет достаточно:
IFS=':'
find $PATH -type f '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')'
Это перечислит полный путь каждого исполняемого файла в ваш $ PATH
. IFS = ':'
обеспечивает разделение $ PATH
на двоеточия (:
), разделитель для этой переменной.
Если вам не нужен полный путь , а только имена исполняемых файлов , вы можете сделать
IFS=':'
find $PATH -type f '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')' -exec basename {} \; | sort
Если ваш find
совместим с GNU , условие немного упрощается:
IFS=':'
find $PATH -type f -executable -exec basename {} \; | sort
Как указывает @StephenHarris, с этим есть небольшая проблема: если есть подкаталоги вашего $ PATH
, файлы в этих подкаталогах могут быть зарегистрированы даже хотя $ PATH
не может связаться с ними. Чтобы обойти это, вам на самом деле понадобится find
с большим количеством параметров, чем требует POSIX.GNU-совместимый может обойти это с помощью:
IFS=':'
find $PATH -maxdepth 1 -type f -executable -exec basename {} \; | sort
-maxdepth 1
сообщает find
не входить ни в один из этих подкаталогов.
IFS=:; set -f;
find -- $PATH -type d -prune -exec sh -c '
cd "$1" && \
find . -type d ! -name . -prune \
-o \
-type f \( -perm -u+x -o -perm -g+x -o -perm -o+x \) -exec echo Executable File: \{\} \; \
-o \
-type f ! -perm -u+x ! -perm -g+x ! -perm -o+x -exec echo Not executable: \{\} \;
' {} {} \;
IFS установлен на двоеточие, разделитель PATH, и сопоставление glob также заблокировано, чтобы исключить любое разделение на символы glob в именах, найденных в PATH.
Затем $PATH разделяется и представляется в качестве ведущих аргументов для find
до получения любых опций. Мы выбираем только те аргументы из них, которые являются каталогами. (Если мы хотим получить ссылки и на dir, то задайте опцию -L).
А затем мы просто ныряем до первого уровня в этих каталогах и выхватываем те файлы, которые являются исполняемыми кем-то (т.е. кем-то из пользователей/групп/других)
Специально для bash вы можете воспользоваться встроенным модулем compgen
:
compgen -c
перечисляет все доступные команды, встроенные модули, функции, псевдонимы и т.д. (по сути, все, что может появиться, если нажать Tab в пустом приглашении). compgen -b
перечисляет все встроенные модули, аналогично d
для каталогов, f
для файлов, a
для псевдонимов и так далее. Так что вы можете использовать вывод compgen
и злоупотреблять which
:
$ compgen -c | xargs which -a
/bin/egrep
/bin/fgrep
/bin/grep
/bin/ls
/bin/ping
/usr/bin/time
/usr/bin/[
/bin/echo
/bin/false
/bin/kill
Первые пять - это фактически псевдонимы, затеняющие команды в моем случае, затем у нас есть ключевые слова и встроенные модули, так что, похоже, есть некоторый порядок в выводе compgen
.