Как распечатать файлы, используя условие not bash - PullRequest
2 голосов
/ 08 мая 2019

Скажем, у меня есть три файла в каталоге dir

touch a.ym b.ym a.job 

И мне нужно напечатать все *.ym, если у него нет соответствующего *.job файла.Итак, это то, что я пробовал,

for file in $(find ${dir} -name \*.ym);do
    filebase=$(basename $file)
    sample_id=$(echo "${filebase}"| awk -F'[.]' '{print $1}')
    if  [[ $sample_id != *".job" ]]; then
          echo "${file}"
    fi
done

Однако вышеприведенное решение распечатывает оба файла

a.ym b.ym, где мне нужно распечатать только файл b.ym

Ответы [ 3 ]

5 голосов
/ 08 мая 2019

Я приветствую вашу изобретательность в использовании инструментов, с которыми вы знакомы, но вы много делаете с командами find и awk, которые можно сделать проще с помощью просто чистых bash.

Попробуйте это:

Ответ

for ym_file in "${dir}"/*.ym; do
    job_file="${ym_file/.ym/.job}"
    if [[ ! -f "$job_file" ]]; then
        echo "${ym_file} has no matching job file"
    fi
done

Объяснение

  • "${dir}"/*.ym: Вы можете использовать совпадение глобуса в bash напрямую. Это приведет к ошибке, если у вас нет файлов .ym, но в этой ситуации ничего плохого не будет.
  • "${ym_file/.ym/.job}": это замена шаблона bash. Он заменяет все экземпляры .ym на .job. Я предполагаю, что эти шаблоны не появятся в вашем имени файла, кроме как в конце.
  • [[ ! -f "$job_file" ]]: флаг -f проверяет наличие обычного файла, а ! отменяет его (поэтому проверяет отсутствие обычного файла).
4 голосов
/ 08 мая 2019

c.f. Расширение параметров Bash и Условные выражения для встроенных инструментов.

for f in *.ym
do [[ -e "${f%.ym}.job" ]] || echo "$f"
done
3 голосов
/ 08 мая 2019

В Bash:

Чтобы обеспечить выполнение исполняемого скрипта с использованием интерпретатора bash, важно убедиться, что первые символы в скрипте #!, а затем команда, которая будетвызвать bash.Пример первой строки:

#!/bin/bash

Обычно расширение шаблона глоба, который ничего не соответствует, приводит к оригинальному шаблону глобинга.Это не желательно в нашем случае.Чтобы сделать несоответствующий глобус оценочным для пустого списка файлов, необходимо включить параметр nullglob следующим образом:

shopt -s nullglob

Следующее выражение оценивает список файлов, имя которых заканчивается на.ym, внутри каталога, $dir:

"$dir"/*.ym

Следующее вычисляет префикс имени файла, $file:

"${file%.*}"

И условие, которое проверяетесли файл не существует:

if [[ ! -f "${file}" ]]; then
  ... the file does not exist ...
fi

Объединение этих точек приводит к следующему сценарию:

#!/bin/bash

shopt -s nullglob

for file in "$dir"/*.ym; do
  if [[ ! -f "${file%.*}.job" ]]; then
    echo "$file"
  fi
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...