私のディレクトリ構造は次のとおりです
Directory1\file1.jpg
\file2.jpg
\file3.jpg
Directory2\anotherfile1.jpg
\anotherfile2.jpg
\anotherfile3.jpg
Directory3\yetanotherfile1.jpg
\yetanotherfile2.jpg
\yetanotherfile3.jpg
Ubuntuのbashシェルでコマンドラインを使用して、各ディレクトリから最初のファイルを取得し、名前をディレクトリ名に変更して、1つ上のレベルに移動して、ディレクトリの横に配置しようとしています。
上記の例では:
file1.jpg
はDirectory1.jpg
に名前が変更され、フォルダDirectory1
の横に配置されます
anotherfile1.jpg
はDirectory2.jpg
に名前が変更され、Directory2フォルダーの横に配置されます
yetanotherfile1.jpg
はDirectory3.jpg
に名前が変更され、フォルダDirectory3
の横に配置されます
私は使ってみました:
find . -name "*.jpg"
しかし、ファイルを順番にリストしていません(最初のファイルが必要です)。
この行:
find . -name "*.jpg" -type f -exec ls "{}" +;
ファイルは正しい順序でリストされていますが、各ディレクトリの最初のファイルだけを選択して1レベル上に移動するにはどうすればよいですか?
何か助けていただければ幸いです!
編集:私が最初のファイルを参照すると、各jpgには0からそのフォルダー内の多くのファイルまでの番号が付けられます-たとえば、file1、file2 ...... file34、file35など...もう1つ言及することはファイルの形式がランダムであるため、番号付けは0または1aまたは1bなどから始まる場合があります。
firstがシェルグロブが最初に検出したものをすべて意味する場合(レキシカルですが、おそらくLC_COLLATE
の影響を受ける)、これでうまくいくはずです。
for dir in */; do
for file in "$dir"*.jpg; do
echo mv "$file" "${file%/*}.jpg" # If it does what you want, remove the echo
break 1
done
done
コンセプトの証明:
$ mkdir dir{1,2,3} && touch dir{1,2,3}/file{1,2,3}.jpg
$ for dir in */; do for file in "$dir"*.jpg; do echo mv "$file" "${file%/*}.jpg"; break 1; done; done
mv dir1/file1.jpg dir1.jpg
mv dir2/file1.jpg dir2.jpg
mv dir3/file1.jpg dir3.jpg
各ディレクトリ内に移動して実行できます:
$ mv `ls | head -n 1` ..
最初のレベルのディレクトリをすべて探し、このディレクトリの最初のファイルを特定して、1レベル上に移動します
find . -type d \! -name . -Prune | while read d; do
f=$(ls $d | head -1)
mv $d/$f .
done
上の答えに基づいて、以下は、指定されたディレクトリ内のファイルに解決される最初のパスを返すだけの一般的なbash関数です。
getFirstFile() {
for dir in "$1"; do
for file in "$dir"*; do
if [ -f "$file" ]; then
echo "$file"
break 1
fi
done
done
}
使用法:
# don't forget the trailing slash
getFirstFile ~/documents/
注:無効なパスを渡した場合、何も返されません。