Строка поиска во многих файлах на HP-UX

Вот сценарий удара. Это не использует 'столбец-t', и разделитель обрабатывается точно, как IFS, потому что это - IFS (или по крайней мере, внутренняя версия awk IFS)... Разделитель по умолчанию является $' \t'

Этот сценарий полностью увеличивает самое правое поле.
'столбец' не делает этого.
Путем увеличивания всех столбцов этот сценарий может быть
легко измененный для создания кадра таблицы также.

Примечание. Входной файл должен быть обработан дважды
('столбец' должен был бы также сделать это),
Первичная обработка должна получить столбец макс. ширины.
Вторая передача должна развернуть поля (для каждого столбца)

Добавленный некоторые опции и исправил явную ошибку (переименовывающий переменные :(

  • - l Левый пробел для обрезки любых полей с отступом
  • - r Право обрезают пробел шире, чем самый широкий текст (для столбца)
  • - b И-l и-r
  • - L Левый выходной разделитель добавляется
  • - R Правильный выходной разделитель добавляется
  • - B И-L и-R
  • - S Выбирают выходной разделитель

#!/bin/bash
#
#   script [-F sep] [file]
#
#   If file is not specified, stdin is read 
#    
# ARGS ######################################################################
l=;r=;L=;R=;O=;F=' ' # defaults
for ((i=1;i<=${#@};i++)) ;do
  case "$1" in
    -- ) shift 1;((i--));break ;;
    -l ) l="-l";shift 1;((i-=1)) ;;        #  left strip whitespace
    -r ) r="-r";shift 1;((i-=1)) ;;        # right strip whitespace
    -b ) l="-l";r="-r";shift 1;((i-=1)) ;; # strip  both -l and -r whitespace
    -L ) L="-L";shift 1;((i-=1)) ;;        #  Left output delimiter is added
    -R ) R="-R";shift 1;((i-=1)) ;;        # Right output delimiter is added
    -B ) L="-L";R="-R";shift 1;((i-=1)) ;; # output Both -L and -R delimiters
    -F ) F="$2";shift 2;((i-=2)) ;; # source separator
    -O ) O="$2";shift 2;((i-=2)) ;; # output  separator. Default = 1st char of -F 
    -* ) echo "ERROR: invalid option: $1" 1>&2; exit 1 ;;
     * ) break ;;
  esac
done
#
if  [[ -z "$1" ]] ;then # no filename, so read stdin
  f="$(mktemp)"
  ifs="$IFS"; IFS=$'\n'; set -f # Disable pathname expansion (globbing)
  while read -r line; do
    printf "%s\n" "$line" >>"$f"
  done
  IFS="$ifs"; set +f # re-enable pathname expansion (globbing)
else
  f="$1"
fi
[[ -f "$f" ]] || { echo "ERROR: Input file NOT found:" ;echo "$f" ;exit 2 ; }
[[ -z "$F" ]] && F=' '        # input Field Separator string
[[ -z "$O" ]] && O="$F"       # output Field Separator
                 O="${O:0:1}" #   use  single char only

# MAIN ######################################################################
max="$( # get max length of each field/column, and output them
  awk -vl="$l" -vr="$r" -vL="$L" -vR="$R" -vF="$F" -vO="$O" '
    BEGIN { if (F!="") FS=F }
    { for (i=1;i<=NF;i++) { 
        if (l=="-l") { sub("^[ \t]*","",$i) }
        if (r=="-r") { sub("[ \t]*$","",$i) }
        len=length($i); if (len>max[i]) { max[i]=len } 
        if (i>imax) { imax=i } 
      } 
    }
    END { for(i=1;i<=imax;i++) { printf("%s ",max[i]) } }
  ' "$f" 
)"

awk -vl="$l" -vr="$r" -vL="$L" -vR="$R" -vF="$F" -vO="$O" -v_max="$max" '
  BEGIN { if (F!="") FS=F; cols=split(_max,max," ") }
  { # Bring each field up to max len and output with delimiter
    printf("%s",L=="-L"?O:"")
    for(i=1;i<=cols;i++) { if (l=="-l") { sub("^[ \t]*","",$i) } 
                           if (r=="-r") { sub("[ \t]*$","",$i) }
      printf("%s%"(max[i]-length($i))"s%s",$i,"",i==cols?"":O) 
    } 
    printf("%s\n",R=="-R"?O:"")
  }
' "$f"

# END #######################################################################    
if  [[ -z "$1" ]] ;then # no filename, so stdin was used
  rm "$f"   # delete temp file
fi
exit
4
19.11.2011, 03:19
3 ответа

Вы могли использовать вариант Вашего find управляйте как это:

find . -type f -exec grep -l word {} \; 
5
27.01.2020, 20:49
  • 1
    Вы забыли писать слово для поиска, таким образом, это не отвечает на проблему, таким образом, это не должно быть лучшим ответом, если Mat не исправляет его. ответ @Gilles лучше и больше завершенное, по моему скромному мнению. –  Gabriel Hautclocq 31.08.2017, 18:32
  • 2
    Хорошо определенный. Не стесняйтесь предлагать редактирования при определении опечаток как этот. –  Mat 31.08.2017, 18:36
  • 3
    Это лучше теперь :-) Еще меньше завершенное, чем ответ Gilles, но работы для всех. –  Gabriel Hautclocq 31.08.2017, 18:50

Если Ваша версия HP-UX является достаточно последней, можно звонить find с -exec … + действие. Это действие делает то же задание как xargs (назовите команду на нескольких файлах соответствия сразу, не переполняя предела длины командной строки), но надежным способом к любому имени файла.

find . -type f -exec grep -l word {} +

Если Ваша версия HP-UX слишком стара, Вы могли бы иметь только -exec … \; и нет -exec … +. ; версия называет команду на одном файле за один раз, который немного медленнее.

find . -type f -exec grep -l word {} \;

Если Ваши имена файлов не содержат \"' или пробел, затем можно использовать xargs без -0 опция.

find . -type f -print | xargs grep -l word
4
27.01.2020, 20:49

Для близкого POSIX-эквивалента grep -l word./*, который разбивает список файлов по мере необходимости, чтобы избежать ограничения execve()на размер аргументов, вы можете сделать:

find -L. ! -name. -prune ! -name '.*' -type f -exec \
  grep -l word /dev/null {} +
  • ! -name. -prune- не возвращаться в подкаталоги -
  • -Lв сочетании с -type fзаключается в поиске только в обычных файлах (после разрешения символической ссылки)(бонус по сравнению с grep..../*подходом, который просматривал бы файлы любого типа)
  • ! -name '.*'для исключения скрытых файлов, как ./*
  • /dev/nullчтобы убедиться, что имя файла всегда печатается (еще один бонус ).

Заметным отличием является то, что список файлов не будет сортироваться.

0
27.01.2020, 20:49

Теги

Похожие вопросы