Команда Unix для проверки отсутствия файла в последовательности - PullRequest
0 голосов
/ 25 июня 2019

Ниже приведен формат файла в папке.

File format - fact_type_<key>_partid
fact_type_123_1
fact_type_123_2
fact_type_123_3
fact_type_123_4
fact_type_124_1
fact_type_124_2
fact_type_124_3
fact_type_124_4
..
fact_type_130_1

Каждый ключ должен иметь 4 файла (i.e Key1 should have 4 files ending with 1, 2, 3 and 4).

Ключи должны быть в последовательности, для приведенного выше примера следующий файл должен быть fact_type_125_1

Вышеуказанные файлы загружаются из внешнего процесса, и следующий процесс завершится неудачей, если у нас нет всех файлов между ключом начала и конца (4 files for each key and all keys starting 123 till 130).

Сейчас я использую cutвведите команду и скопируйте данные в Excel, а затем найдите все недостающие ключи

ls -1a | cut -d '_' -f3 | sort | uniq 

Пожалуйста, помогите мне с командой, чтобы проверить это в папке.

Ответы [ 3 ]

1 голос
/ 25 июня 2019

С bash и GNU sort:

for f1 in fact_type_*; do
  echo "${f1%_[0-9]}"
done | sort -u |\
while read -r f2; do
  for ((i=1; i<=4; i++)); do
    f="${f2}_${i}"
    [[ ! -e "$f" ]] && echo "missing $f"
  done
done

Вывод (например):

missing fact_type_126_4
missing fact_type_127_1
missing fact_type_127_2
missing fact_type_127_4
0 голосов
/ 25 июня 2019

С GNU awk для массивов массивов и sorted_in:

$ cat tst.awk
BEGIN {
    for (i=1; i<ARGC; i++) {
        fname = ARGV[i]
        split(fname,fparts,/_/)
        key = fparts[3]
        id  = fparts[4]
        ids[key][pid]
    }
    PROCINFO["sorted_in"] = "@ind_num_asc"
    for (key in ids) {
        if ( (prevKey != "") && (key != prevKey+1) ) {
            printf "key gap: %s -> %s\n", prevKey, key | "cat>&2"
        }
        prevId = ""
        idCnt = 0
        for (id in ids[key]) {
            if ( (prevId != "") && (id != prevId+1) ) {
                printf "id gap: %s, %s -> %s\n", key, prevId, id | "cat>&2"
            }
            if (id !~ /^[1234]$/) {
                printf "bad id: %s, %s\n", key, id | "cat>&2"
            }
            idCnt++
            prevId = id
        }
        if (idCnt != 4) {
            printf "bad id count: %s, %s\n", key, idCnt | "cat>&2"
        }
        prevKey = key
    }
}

$ awk -f tst.awk *
0 голосов
/ 25 июня 2019

Итак, ограничения:

Каждый ключ должен иметь 4 файла

Ключи должны быть в последовательности

Итак, я сделал это:

  • Сначала нам нужно получить все файлы
  • , затем нам нужны ключи max и min
  • , затем нам нужно сгенерировать последовательность из ключей min и max с каждым {1..4} суффиксы
  • тогда нам нужно проверить для каждой записи, существует ли файл

Сценарий:

check() {
  local keys
  keys=$(
    # find all the files
    find "$1" -regex '.*/fact_type_[0-9]+_[0-4]' \
      -type f -printf "%f\n" |
    # extract the keys
    cut -d_ -f3
  )

  if [ -z "$keys" ]; then
    echo "No files found"
    return 255
  fi

  local nonexisting
  nonexisting=$(
    # sort it
    <<<"$keys" sort |
    # extract first and last key only
    sed -n '1p;$p' |
    # generate sequence
    xargs seq |
    # append {1..4} to all keys
    xargs -i printf "%s\n" "fact_type_{}_"{1..4} |
    # print only nonexisting files
    xargs -l sh -c '[ ! -e "$1" ] && printf "%s\n" "$1"' --
  )

  if [ -n "$nonexisting" ]; then
    <<<"$nonexisting" xargs printf "File %s does not exists\n"
    return "$(<<<"$nonexisting" wc -l)"
  fi
}

touch fact_type_{123..130}_{1..4}

check .  # all ok

rm fact_type_130_1
rm fact_type_125_4
check .  # two files missing

выведет (первый check . ничего не выводит, второй только выводит):

File fact_type_125_4 does not exists
File fact_type_130_1 does not exists

проверено на repl .

...