создать пару файлов с соответствующими расширениями - PullRequest
1 голос
/ 28 марта 2011

Допустим, у меня есть этот список файлов:

a.1
a.2
a.3
стр.1
б.2

Есть ли в bash однострочник, который может найти один файл 'a', для которого нет 'b' с таким же расширением? (т. е. a.3: нет совпадения )
Я уверен, что мог бы написать короткий bash / perl-скрипт для этого.
Но я хотел бы знать, есть ли для этого какой-то «трюк» (конечно, в моем распоряжении инструменты GNU; awk, sed, find ...)

Ответы [ 5 ]

2 голосов
/ 28 марта 2011

Вот мой однострочный bash

for afile in a*; do bfile=${afile/a/b}; test -f $bfile || echo $afile; done

Мне нравится вышеупомянутое решение, поскольку оно использует только bash и никаких других инструментов.Однако, чтобы продемонстрировать мощь инструментов Unix, в следующем решении используются 4: ls, sed, sort и uniq:

ls [ab]* | sed 's/b/a/' | sort | uniq -u
2 голосов
/ 28 марта 2011

Вы можете попробовать это:

ls -1 [ab].* | sort -t . -k 2 | uniq -u -s2
1 голос
/ 28 марта 2011

Рубин (1,9 +)

$ ruby -e 'Dir["a.*"].each{|x|puts x if not File.exist? "b."+x.scan(/a\.(\d+)/)[0][0]}'
1 голос
/ 28 марта 2011

bash версии 4 имеет ассоциативные массивы, так что вы можете сделать это:

declare -A a_files
while read -r filename; do
    ext="${filename##*.}"
    case "${filename%.*}" in 
        a) a_files[$ext]="$filename" ;;
        b) unset a_files[$ext] ;;
    esac
done < <(ls [ab].*)
echo "non-matched 'a' files: ${a_files[@]}"

Или с помощью awk:

ls [ab].* | awk -F. '
    $1 == "a" {a_files[$2] = $0} 
    $1 == "b" {delete a_files[$2]}
    END {for (ext in a_files) print a_files[ext]}
'
1 голос
/ 28 марта 2011

Если вы можете использовать Perl:

perl -le 'for (<a*>) { /(.*)\.(.*)/; print "$1.$2" if !-e "b.$2"}'
...