各ファイルの3行目のテキストが新しいファイル名になるように、多数のファイル名を変更するソリューションを考案したいと思います。これらのファイルはすべて同じ構造を持っています。
これはHTMLファイルです。特に、各ファイルの3行目は次のとおりです。
<TITLE>DATA POPULATION 'CODE on group 1234 by THING'</TITLE>
一重引用符の間のすべての内容を取得し、そのテキストを使用してそのテキストをファイル名に変更したいと思います。
一度に名前を変更すると便利です。
答え1
for src in *.html; do
{ read -r x && read -r x && IFS="'" read -r x dst x; } < "$src" &&
mv -i -- "$src" "$dst.html"
done
(-i
これはインタラクティブ両方のファイルが同じ宛先名で終わる場合、ユーザーにファイルの損失を防ぐ機会を与えます。
答え2
$ awk -v FS="'" -v OFS="\t" 'FNR==3 && NF>2 {print FILENAME, $2; nextfile}' *.txt |parallel --colsep "\t" 'mv {1} {2}'
awk
その場所のすべてのファイルを繰り返します。'
フィールド区切り文字として定義します。 3行目に達し、2つ以上のフィールドがあるたびに(2つのフィールドがある場合は必ず)、'
タブ(最初の2つのフィールド間のフィールド)で区切られたファイル名と2番目のフィールドを印刷します。'
次に、次のファイルに移動します。
結果はにパイプされますparallel
。とを結果列の値に置き換えてコマンドを実行しますparallel
。mv
{1}
{2}
awk
いくつかの注意:
nextfile
すべてのawk
バージョンが利用できるわけではありません。ファイル名にスペースを使用することは決して良い考えではありません。次のようにコマンドを変更した場合は、
awk
下線で置き換えることができます。awk -v FS="'" -v OFS="\t" 'FNR==3 && NF>2 { gsub(" ", "_", $2); print FILENAME, $2; nextfile}' *.txt
- 新しいファイル名を別のフォルダに移動またはコピーする必要があります。
awk
実行時に同じフォルダに新しいファイルが表示された場合、どのように反応するのかわかりません。
答え3
for j in ./*.txt
do
i=$( sed -n '3p' "$j" | cut -d "'" -f2)
mv "$j" "$i"
done
現在のディレクトリ内のすべてのファイルを検索して、そのファイルを新しいディレクトリに移動します。
答え4
遅くて壊れやすいサブシェルを一緒に使用するのではなく、Perlで次のことを行います。
perl -e 'while(<>){
sub no_rename { print "rename @_\n" }
next unless $. == 3;
if(my ($f) = /DATA POPULATION +'\''(.*?)'\''/){
$f =~ s/[^\w]/_/g;
no_rename $ARGV, $f or warn "rename $ARGV, $f: $!\n";
}
close ARGV
}' files ...
表示するのではなく、実際に実行するようにno_rename
変更する必要があります。rename
醜いので申し訳ありません'\''
。 1行ではなくスクリプトファイルに入れるのは簡単です。
/DATA POPULATION +'(.*?)'/
スペースを含むファイル名を作成したい場合は、式の後に\s
スペースを追加することもできます(ファイル名に表示される他の文字と同様に - デフォルトでは、スクリプトは文字と数字を除くすべてを下線に置き換えます)。\w
s///g