1

私は 4 つのディレクトリ (名前: 英語、アラビア語、フランス語、ロシア語) を持っています。これらのディレクトリには、名前は同じで拡張子が異なるファイルがいくつかあります。そのようなファイルの例を次に示します。

MyFile104.en
MyFile104.ar
MyFile104.fr
MyFile104.ru

ファイルがディレクトリに存在するが、他のディレクトリから削除されている場合があります (たとえば、"MyFile23.ar" と "MyFile23.en" だけが存在します)。

私がやりたいことは、これらのディレクトリのファイル名を比較し、すべてのディレクトリに存在しないファイルを削除することです。

これどうやってするの?

4

3 に答える 3

0

連想配列をサポートする Bash 4 を使用している場合:

#!/bin/bash
declare -A languages
languages["English"]=en
languages["Arabic"]=ar
languages["French"]=fr
languages["Russian"]=ru

for language in "${!languages[@]}"
do
    for file in MyFile*."${languages[language]}"
    do
        rmflag=false
        for compare in "${!languages[@]}"
        do
            compfile=compare/${file##*/}
            compfile=${compfile%.${languages[language]}}.${languages[compare]}
            if ! $rmflag && [[ ! -e $compfile ]]
            then
                rm "$file"
                rmflag=true
            elif $rmflag && [[ -e $compfile ]]
            then
                rm "$compfile"
            fi
        done
    done
done

これはテストされておらず、準拠していないファイルがあるMyFile*.{en,ar,fr,ru}場合、またはメイン ディレクトリの下にディレクトリがある場合、希望どおりに動作しない可能性があります。

Bash 3 または 4 で動作するはずの別のバージョンを次に示します。

#!/bin/bash
for dir in English Arabic French Russian
do
    for file in "$dir"/*
    do
        base=${file##*/}
        base=${base%.*}
        files=({English,Arabic,French,Russian}/"$base".{en,ar,fr,ru})
        if (( ${#files[@]} != 4 ))
        then
            rm -f {English,Arabic,French,Russian}/"$base".{en,ar,fr,ru}
        fi
    done
done

繰り返しますが、テストされていません。以前と同じ条件下で、またはファイルが間違った場所にある場合 (たとえば、イギリス人がフランスを訪れた場合など) は、期待どおりの結果が得られない可能性があります。;-)

于 2012-06-24T19:17:19.793 に答える
0
# create test environment
$ for i in ar fr ru en; do mkdir -p $i; touch $i/t1.{fr,en,ru,ar}; done
$ rm en/t1.fr

# print filenames to be deleted (less than 4 occurances)
$ find ar en fr ru  -name t1.'*' | sed 's/^.*\///' | sort | uniq -c | awk '$1!=4{print $2}'

# remove files with less than 4 occurances
$ find ar en fr ru -name $(find ar en fr ru  -name t1.'*' | sed 's/^.*\///' | sort | uniq -c | awk '$1!=4{print $2}') -delete
于 2012-06-25T18:04:29.357 に答える
0

指定された拡張子を持つすべてのファイルが処理されます。指定したディレクトリのサブディレクトリは無視されます。指定されたもの以外のファイル拡張子は無視されます。名前が指定された .extensions のいずれかで終わり、指定されたすべてのディレクトリに存在しないファイルは削除されます。

注: スクリプトは、処理中のディレクトリに間違ったファイル拡張子を持つファイルがないことを前提としています。たとえば、ディレクトリ内の任意の.arまたは.enまたはは、望ましくない結果を引き起こす可能性があります! ..frRusian

langs=( Arabic English French Russian )
extns=( ar en fr ru )
rxext="${extns[@]}" 
rxext="${rxext// /\\|}"  # regex: for .extensions

find "${langs[@]}" -maxdepth 1 -type f -regex ".*\.\($rxext\)$" -printf '%f\n' |
  sed -n "s/\(.*\)\..*$/\1/p" | sort | uniq -c |           # name is in how many dirs?
    sed -n "/^ *${#langs[@]} \(.*\)/!{s/^ *[0-9]\+ //p}" | # names not in all dirs
      xargs -I {} find "${langs[@]}" -maxdepth 1 -type f -regex ".*\/{}\.\($rxext\)$" |
        xargs -I {} rm {}

特定の言語のディレクトリにある非母国語の拡張子を持つファイルを保持して無視したい場合は、次のスクリプトがまさにそれを行います。

all="/tmp/all_${0##*/}"
del="/tmp/del_${0##*/}"

extns=( ar     en      fr     ru      )
langs=( Arabic English French Russian )

# list names (not paths) whose extensions match a given directory
for (( i=0; i<${#extns[@]}; i++ )) do
  find "${langs[i]}" -maxdepth 1 -type f -name "*.${extns[i]}" -printf '%f\n'
done >"$all"

# list names not in all dirs
sed -nr "s/(.*)\..*$/\1/p" "$all" | sort | uniq -c |         # name is in how many dirs?
  sed -nr "/^ *${#extns[@]} (.*)/!{s/^ *[0-9]+ //p}" >"$del" 

# list names in deficit; add paths; then delete files
grep -F -f "$del" "$all" |
  sed -r "$(for (( i=0; i<${#extns[@]}; i++ )) ;do
              echo "s/.*\.${extns[i]}$/${langs[i]}\\/&/;t;"
            done)" | xargs -d "\n" rm

rm "$all" "$del"
于 2012-06-24T22:07:13.000 に答える