Фильтровать дубликаты имен файлов с помощью tar

Я использую tar как это,

tar -cjpvf a.tar "$pattern1" "$pattern2" 

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

Например, следующий пример добавляет две дубликаты записи в архив

 %> tar -cjpvf a.tar /etc/passwd /etc/passwd %> tar -xvf a.tar etc/passwd etc/passwd и %> tar -cjpvf a.tar /etc/passwd /etc/passwd %> tar -xvf a.tar etc/passwd etc/passwd 

Как я могу отфильтровать их?

  • Использовать все хосты, завершенные zsh для cssh
  • aptitude remove pkg_name * не работает как apt-get
  • Где scp помещал эти файлы?
  • Способ записи нового имени файла на подстановочный знак?
  • Передача путей и имен файлов в программу из сценария bash
  • Чтение каталога в сценарии оболочки
  • Проблемы с basename в цикле
  • Как удалить 2 месяца назад файлы в unix
  • 3 Solutions collect form web for “Фильтровать дубликаты имен файлов с помощью tar”

    Если pattern2 и pattern2 являются шаблонами шаблонов оболочки, вы можете использовать or-pattern.

     tar -cjpvf a.tar @($pattern1|$pattern2) 

    Для этого требуется ksh, bash или zsh. В bash вам нужно shopt -s extglob запустить shopt -s extglob чтобы активировать синтаксис шаблона @(…) . В zsh вам нужно setopt ksh_glob запустить setopt ksh_glob (а также указать zsh, что переменные содержат шаблоны, а не строки, поэтому @($~pattern1|$~pattern2) ) или использовать собственный синтаксис ($~pattern1|$~pattern2) .

    Если вам удобно разбирать вывод ls (и здесь, предполагая, что ни одно из имен файлов не содержит символов $IFS или подстановочных знаков или начинается с - ):

     tar -cjpvf a.tar $(ls -d1 <pattern1> <pattern2> | sort | uniq) 

    или

     tar -cjpvf a.tar $(ls -d1 <pattern1> <pattern2> | sort -u) 

    Если вам неудобно разбирать вывод ls , правильным подходом является использование find (здесь предполагается GNU tar или совместимый):

     find -maxdepth 1 \( -name <pattern1> -o -name <pattern2> \) -print0 \ | xargs -0 tar -cjpvf a.tar 

    (здесь предполагается, что список файлов достаточно мал, чтобы запустить только один вызов tar . Также обратите внимание, что find не пропускает скрытые файлы по умолчанию).

    Если порядок имеет значение. Например, если вы хотите архивировать файлы foo* и *.txt , и вы хотите, чтобы foo* файлы отображались сначала в архиве (но foo.txt не включался дважды). IOW, получите foo.a foo.b foo.txt foo.z a.txt b.txt z.txt в следующем порядке:

    С zsh :

     files=(./foo*(N) ./*.txt(N)) (($#files)) && tar jcf file.tar.bz2 ${(u)files} 

    С tcsh :

     set -f files = (./foo* ./*.txt) && tar jcf file.tar.gz2 $files:q 

    Если вы хотите убедиться, что *.txt являются последними ( foo.a foo.b foo.z a.txt b.txt foo.txt z.txt в этом порядке):

    С zsh :

     files=(./foo*(N) ./*.txt(N)) (($#files)) && tar jcf file.tar.bz2 ${(uOa)${(Oa)files}} 

    ( Oa – флаг расширения параметра, который меняет порядок массива)

    С tcsh :

     set -l files = (./foo* ./*.txt) && tar jcf file.tar.gz2 $files:q 
    Linux и Unix - лучшая ОС в мире.