Как динамически исключить файлы из вывода ls? - PullRequest
0 голосов
/ 07 января 2019

Я выполняю команду:

echo $(ls -p "/root/arch" -1tr | grep -v / )
20190107224626.ogg 20190107224705.ogg 20190107224720.ogg 20190107224645.ogg

Я получаю весь список файлов, отсортированных по самому старому (со дня создания). Все работает как надо.

Также необходимо сделать динамическое исключение файлов (есть файлы с такими же именами, но с расширением .lock и в другой папке):

echo $(ls -p "/root/pids" -1tr | grep -v / )
20190107224645.ogg.lock 20190107224705.ogg.lock

Я выполняю команду:

echo $(ls -1tr /root/pids/*.lock | awk -F/ '{print $NF}' | grep -Po '.*(?=\.)' | while IFS= read -r line; do echo "-I \"$line\" "; done)
-I "20190107224645.ogg" -I "20190107224705.ogg"

Теперь я пытаюсь объединить все это в одну строку, но это не работает должным образом (я получаю все 4 файла вместо двух), что я делаю неправильно и как я могу это исправить?

echo $(ls -p "/root/arch" -1tr $(ls -1tr /root/pids/*.lock | awk -F/ '{print $NF}' | grep -Po '.*(?=\.)' | while IFS= read -r line; do echo "-I \"$line\" "; done) | grep -v / )
20190107224626.ogg 20190107224705.ogg 20190107224720.ogg 20190107224645.ogg

Ответы [ 3 ]

0 голосов
/ 07 января 2019

Вот сравнительно простая однострочная строка для этого с использованием потоковой манипуляции:

ls -p /root/{arch,pids} | grep -v / | sed 's/\.lock//g' | sort | uniq -u | xargs -l
0 голосов
/ 07 января 2019

Если я вас правильно понимаю -

echo $(
  for f in /root/arch/*               # get each item
  do n="${f##*/}"                     # strip path
     [[ -e "/root/pids/$n.lock" ]] || # if there's NO matching lock
         printf "%s\n" "$n"           # then print the stripped filename
  done | sort -n                      # through a numeric sort
)                                     # to be stacked on one line by echo

Это что-то упустило?

0 голосов
/ 07 января 2019

Если за короткое время я узнал одну вещь, читая ТАК вопросы, помеченные , то это то, что при синтаксическом анализе вывода ls не одобряется.

Альтернативный подход ниже. Он перебирает каждый файл в arch/ и, если не находит соответствующего имени файла с суффиксом .lock в pids/, выводит имя файла:

find arch -type f -printf '%f\0' | while IFS= read -r -d '' line; do
    if [[ ! -e pids/$line.lock ]]; then
      echo "$line"
    fi
done | sort -n

Результат:

20190107224626.ogg
20190107224720.ogg
...