階層的なサブディレクトリが複数あり、パターンファイルを含むすべてのディレクトリを新しい親ディレクトリに再配置しようとしています。パターンに一致するファイルに加えてファイルがあるかどうかに関係なく、移動したいディレクトリの内容を保持したいと思います。
たとえば、
homedir/subdir/{file.txt, file.png, file.rtf}
homedir/subdir/{file.txt, file.png}
homedir/subdir/{file.txt, file.jpg}
homedir/subdir/subdir/{file.png, file.png, file.mp3}
「*.png」(およびディレクトリにある可能性のある他のすべての非pngコンテンツ)を含むすべてのディレクトリを/ dirPNGに移動したいと思います。
したがって、結果は次のようになります。
homedir/subdir/{file.txt, file.jpg}
homedir/dirPNG/subdir/{file.txt, file.png, file.rtf}
homedir/dirPNG/subdir/{file.txt, file.png}
homedir/dirPNG/subdir/subdir/{file.png, file.png, file.mp3}
答え1
ネストされたバージョンを使用できますfind
。このバージョンでは、andをfind
サポートするGNUまたは同様のエントリが必要です。-maxdepth
-quit
解決策使用することができるPOSIX互換性。
find homedir -depth -type d \
-exec sh -c '[ -n "$(find "$@" -maxdepth 1 -type f -name "*.png" -print -quit)" ]' _ {} \; \
-exec sh -c 'echo "Move $@"' _ {} \;
あるときは交換またはecho "Move $@"
補充してください。mv "$@" /dirPNG
絶対に確実コードが望むことをしています。
まず、ディレクトリを深く探索して*.png
各ディレクトリで一致するファイルを検索するように機能します。一致するものがあれば、ディレクトリが移動されます。
homedir/subdir
したがって、インクルードsubsubdir/a.png
とがある場合は、前に移動してb.png
階層ディレクトリではなくターゲットディレクトリのピアになります。subsubdir
subdir
目的の結果が得られなかった場合は削除を試みることができますが、移動されたディレクトリナビゲーションに移動しようとすると-depth
多くの種類のエラーが発生します。これは致命的ではありませんが、非常にエレガントではありません。find: ‘subdir’: No such file or directory
find
それにもかかわらず、ディレクトリをターゲットに移動しようとすると(同じ名前のディレクトリがすでに存在する場合)、エラーが発生します。この場合、何が起こるべきかを指定しなかったので、エラーが発生し、移動が拒否されるだけで十分です。
答え2
以下は、必要なタスクを実行するスクリプトです。現在行っている作業をホームディレクトリに適用すると危険です。
以下のスクリプトバッチファイルの作成タスクを実行します。
これを通して事前に予想されるアクションを確認してください。実際に問題を引き起こす可能性がある行を削除できるようにします。
スクリプトには、将来の拡張機能について検討することをお勧めする他の説明があります。
#!/bin/sh
BASE=`basename "$0" ".sh" `
TMP="/tmp/tmp.$$.${BASE}" ; rm -f ${TMP}
START=`pwd`
BATCH="${START}/${BASE}.batch"
MODE=0
INSENS=0
ONE_PARTITION=""
while [ $# -gt 0 ]
do
case "${1}" in
"--suffix" ) MODE=1 ; STRNG="${2}" ; pattern_ident="RELOC_${STRNG}" ; shift ; shift ;;
"--prefix" ) MODE=2 ; STRNG="${2}" ; pattern_ident="RELOC_${STRNG}" ; shift ; shift ;;
"--single" ) ONE_PARTITION="-xdev" ; shift ;;
"--insensitive" ) INSENS=1 ; shift ;;
* ) echo "\n\t ERROR: Invalid option used on command line. Options allowed: [ --suffix | --prefix ] \n Bye!\n" ; exit 1 ; ;;
esac
done
if [ ${MODE} -eq 0 -o -z "${STRNG}" ] ; then echo "\n\t ERROR: Must specify one of --suffix or --prefix values on the command line.\n Bye!\n" ; exit 1 ; fi
SEARCH_ROOT="${HOME}"
RELOCN_DIR="${HOME}/${pattern_ident}"
if [ ! -d "${RELOCN_DIR}" ]
then
mkdir "${RELOCN_DIR}"
if [ $? -ne 0 ] ; then echo "\n\t ERROR: Unable to create target directory for directory relocation actions.\n Bye!\n" ; exit 1 ; fi
fi 2>&1 | awk '{ printf("\t %s\n", $0 ) ; }'
### Ignore start directory itself
### Handling directories with spaces/characters in their name
rm -f "${TMP}.search"*
### Segregate dot dirs from others
find "${SEARCH_ROOT}" -mindepth 1 -maxdepth 1 -type d -print | sort >"${TMP}.search.raw"
awk -F \/ '{ if( index( $NF, "." ) == 1 ) { print $0 } ; }' <"${TMP}.search.raw" >"${TMP}.search"
awk -F \/ '{ if( index( $NF, "." ) == 0 ) { print $0 } ; }' <"${TMP}.search.raw" >>"${TMP}.search"
##########
#more "${TMP}.search"
#exit 0
##########
while read SEARCH_dir
do
if [ -z "${SEARCH_dir}" ] ; then break ; fi
echo "\t Scanning: ${SEARCH_dir} ..." >&2
### insert function to dynamically remap ${PAT} to expanded set for case insensitive
if [ ${INSENS} -eq 1 ]
then
sPAT="[Pp][Nn][Gg]"
else
sPAT="${STRNG}"
fi
##########
#echo "sPAT = ${sPAT}" >&2
#exit 0
##########
case ${MODE} in
1)
#########
#( eval find \"${SEARCH_dir}\" ${ONE_PARTITION} -type f -name \'\*\.${sPAT}\' -print | awk -F'/[^/]*$' '{print $1}' | more >&2 ) <&2
#exit 0
#########
eval find \"${SEARCH_dir}\" ${ONE_PARTITION} -type f -name \'\*\.${sPAT}\' -print |
awk -F'/[^/]*$' '{print $1}' | sort | uniq
;;
2)
eval find \"${SEARCH_dir}\" ${ONE_PARTITION} -type f -name \'${sPAT}\*\' -print |
awk -F'/[^/]*$' '{print $1}' | sort | uniq
;;
esac
done <"${TMP}.search" >"${TMP}.dirsToMove"
if [ ! -s "${TMP}.dirsToMove" ] ; then echo "\n\t No directories identified for specified pattern. No action taken.\n Bye!\n" ; exit 0 ; fi
echo "\n Starting directory move ..."
#########
#more "${TMP}.dirsToMove"
#exit 0
########
###
### Doing the action direction without a specific visual review could corrupt
### the HOME directory to point of unusability if the wrong directories are acted upon.
###
### Save all action commands into a batch file for manual visual review
### to confirm sanity of actions identified before applying.
###
rm -f "${BATCH}"
while read DirToMove
do
if [ -n "${DirToMove}" ]
then
new=`echo "${DirToMove}" | eval sed \'s\+${SEARCH_ROOT}/\+\+\' `
echo "mv -fv \"${DirToMove}\" \"${RELOCN_DIR}/${new}\" " 2>&1 | awk '{ printf("%s\n", $0 ) ; }' >>"${BATCH}"
fi
done <"${TMP}.dirsToMove"
if [ ! -s "${BATCH}" ] ; then echo "\n\t No directories identified for specified pattern. No action taken.\n Bye!\n" ; exit 0 ; fi
echo "\n Directory move BATCH file was created:\n"
cat "${BATCH}" | awk '{ printf("\t %s\n", $0 ) ; }'
echo ""
wc -l "${BATCH}"
exit 0
exit 0
exit 0