
次のような名前のファイルがたくさんあります:
name_file-1.txt
name_file-2.txt
name_file-3.txt
some_other_file-1.txt
some_other_file-2.txt
ファイル名には何千種類もの異なる名前があり、-1.txt
末尾に 1 つだけのものもあれば、、... が付くものもあり-1.txt
ます-2.txt
。-60.txt
各ファイルの最大番号をコピーする必要があるのですがname_file-3.txt
、some_other_file-2.txt
Linux のコマンド ラインでこれを実行するにはどうすればよいですか?
答え1
とzsh
:
typeset -A greatest
for f (*-*(n)) greatest[${f%-*}]=$f
cp -- $greatest /destination
*-*(n)
-
: 名前に(*-*
) が含まれ、数値順にソートされた非隠しファイル((n)
glob 修飾子)。${f%-*}
: ファイル名の右端までの部分-
( がない場合は末尾まで-
)。$greatest
: 空でない値に展開します価値観連想配列の。したがって、ここでは、同じルートを共有するファイルの場合、最大の番号を持つファイルのみが展開されます。
答え2
files=(*)
mapfile -t prefixes < <(printf "%s\n" "${files[@]%-*}" | sort -u)
for p in "${prefixes[@]}"; do ls -v "$p"* | tail -1; done
name_file-3.txt
some_other_file-2.txt
そして、それらを他のディレクトリにコピーするには:
for ...; done | xargs cp -t /destination/directory
答え3
ファイルが現在の作業ディレクトリにあり、その名前がサンプル (数字の前に 1 つのダッシュが付く) に準拠している場合は、次の POSIX 準拠のパイプラインが機能するはずです。
ls | sort -t- -k1,1 -k2,2rn | awk -F- 'k!=$1 {print; k=$1}' | pax -rw /path/to/dir
awk コンポーネントは、ソートの -u オプションが安定している場合 (つまり、セットの最初の行が常にそのセットを表すために選択される場合)、ソート -u で置き換えることができます。POSIX ではこの安定性は要求されていませんが、マニュアルによると、{Free、Net、Open}BSD および GNU 実装では安定性が提供されています。運命を試すのが好きなら、次のことを行ってください。
ls | sort -t- -k1,1 -k2,2rn | sort -mut- -k1,1 | pax -rw /path/to/dir
どちらの場合も、ターゲット ディレクトリは現在の作業ディレクトリ内にあってはなりません。
答え4
より信頼性が高くカスタマイズ可能なファイル名解析を行うために、ファイルをタブ区切りの部分に分割し、awk を使用してそれぞれの最高ランクを見つけてレポートします。次に進む前に、まずパイプラインの各部分を試してください。
find DIR -type f <other find criteron> -print |
perl -lne 'print join("\t",(/^(.*?-)(\d+)(\.\w+)$/))' |
awk -F\\t '$2 > f[$1] { f[$1]=$2;e[$1]=$3; } END { for (k in f) { print k f[k] e[k] }}' |
xargs cp -t <desination_directory>
awk スクリプトは、各ファイル名を関連する配列エントリに格納し、常に見つかった最高ランクを保持します。拡張子は独自の配列に格納されます。すべての入力が処理された後、すべての配列エントリが 1 行に 1 つずつ出力されます。このxargs cp -t
行は、すべてのファイルを指定したディレクトリにコピーします。
もう一つの方法があります動作しません数字が 9 より大きく、0 で埋められていない場合は、非常にうまくいきます。この方法では、ファイルを辞書順に並べ替え、リストを解析するときに最初の部分が変更され、最後に表示されたファイル名が使用されます。ファイル名が次のような場合、この方法は機能しません。
file-9.txt
file-10.txt
なぜなら、file-10.txt は file-9 の前に現れるからです。上記の awk スクリプトは数値比較を行います。
注意: タブと改行を含むファイル名は、この処理を阻害します。
注意 2: ファイル名プレフィックスごとに複数の拡張子が可能な場合は、正しく動作するようにいくつかの調整を行う必要があります。